C++程序设计语言学习笔记:派生类

C++程序设计语言学习笔记:派生类,第1张

1、派生类继承了来自基类的属性,因此这种关系称为继承。有时基类也称为超类,派生类也成称为子类。

//基类Employee
struct Employee{
    string first_name, family_name;
    char middle_initial;
    Date hiring_date;
    short department;
    //...
};
//派生类Manager
struct Manager: public Employee{
    list group;
    short level;
    //...
};

按这种方式从Employee派生Manager,使得Manager成为Employee的一个子类型,从而在任何接受Employee的地方都可以使用Manager。

2、派生类的成员可以使用基类的公有和保护成员,就好像它们声明在派生类中一样。

3、一个派生类自身也可以作为其他类的基类。

4、虚函数机制允许程序员在基类中声明函数,然后在每个派生类中重新定义这些函数,从而解决了类型域方法的固有问题。

5、如果派生类中一个函数的名字和参数类型与基类中的一个虚函数完全相同,则称它覆盖了虚函数的基类版本。

6、使用作用域解析运算符::调用函数能保证不使用virtual机制。

7、对于派生类的覆盖控制:

  • virtual,函数可能被覆盖。
  • =0,函数必须是virtual的,且必须被覆盖。
  • override,函数要覆盖基类中的一个虚函数。
  • final,函数不能被覆盖。

8、我们可以显式说明想要进行覆盖:

class Derived:public Base{
    void f() override;
    void g() override;
};

void Derived::f() override    //错误:类外不能使用override
{
    //...
}

void g()                      //正确
{
    //...
}

9、当我们想关闭覆盖,即在类层次中,存在不应被再覆盖的函数,应该将其声明为final。

struct Node{
    //interface class
    virtual Type type() = 0;           //应该被覆盖
    //...
};

class If_statement:public Node{
public:
    Type type() override final;        //防止进一步覆盖
    //...
};

class Modified_if_statement:public If_statement{
public:
    Type type() override;              //错误:If_statement::type() 为final
    //...
};

通过在类名加上final,我们可以将一个类的所有virtual成员函数都声明为final的。

final也不可以在类外使用。

class Derived:public Base{
    void f() final;
    void g() final;
};

void Derived::f() final        //错误:在类外使用final
{
    //...
}

void g() final                 //正确
{
    //...
}

10、用using声明将一个函数加入到作用域中。我们可以使用多个using声明从多个基类引入名字。

11、覆盖函数的类型必须与它所覆盖的虚函数的类型完全一致,C++对这一规则提供了一种放松规则。即,如果原返回类型为B*,则覆盖函数的返回类型可以为D*,只要B是D的一个公有基类即可。类似的,返回类型B&可放松为D&。这一规则有时称为协变返回规则。

12、表示一个抽象概念,自身不能有具体对象,这样的类称为抽象类。使用“伪初始化器”=0,将虚函数声明为纯虚函数。具有一个或多个纯虚函数的类称为抽象类。这样我们无法创建抽象类的对象。对一个抽象类来说,定义一个虚析构函数通常很重要,由于抽象类提供的接口不能用来创建对象,因此抽象类通常没有构造函数。

class Shape
{
public:
    virtual void rotate(int) = 0;        //纯虚函数
    virtual void draw() const = 0;       //纯虚函数
    virtual bool is_closed() const = 0;  //纯虚函数
    //...
    virtual ~Shape();                    //虚函数
};

抽象类只能用作其他类的接口。

class Point{/* ... */};

class Circle:public Shape{
public:
    void rotate(int) override {};
    void draw() const override;
    bool is_closed() const override{return true;}

    Circle(Point p, int r);
private:
    Point center;
    int radius;
};

13、一个类成员可以是private、protected和public的:

  • 如果它是private的,仅可被所属类的成员函数和友元函数所使用。
  • 如果它是protected的,仅可被所属类的成员函数和友元函数以及派生类的成员函数和友元函数所使用。
  • 如果它是public的,可被任何函数所使用。

14、类似成员,基类也可以声明为private、protected或public。不同的访问说明符满足不同的设计需求:

  • public派生令派生类称为基类的一个子类型。
  • private基类最有用的情形就是当我们定义一个类时将其接口限定为基类,从而可提供更强的保障。
  • protected基类在类层次中很有用,其中进一步的派生是常态。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/786083.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-04
下一篇 2022-05-04

发表评论

登录后才能评论

评论列表(0条)

保存