C++复习(四)

1、继承

继承方式/类成员 public成员 protected成员 private成员
public 派生类中public成员 派生类中protected成员 派生类中不可见
protected 派生类中protected成员 派生类中protected成员 派生类中不可见
private 派生类中private成员 派生类中private成员 派生类中不可见

2、优先使用对象组合,而不是继承

  • 继承允许你根据基类类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,基类的内部细节对子类可见 。继承一定程度破坏了基类的封装,基类的改变,对派生类类有很大的影响。派生类和基类间的依赖关系很强,耦合度高。
  • 对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。 组合类之间没有很强的依赖关系,耦合度低。优先使用对象组合有助于你保持每个类被封装

3、基类和派生类之间的赋值转换

  • 派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。这里有个形象的说法叫切片或者切割。寓意把派生类中父类那部分切来赋值过去。
  • 基类对象不能赋值给派生类对象
  • 基类的指针可以通过强制类型转换赋值给派生类的指针。但是必须是基类的指针指向派生类对象时才是安全的

4、实现一个不能被继承的类

如果在c++98中那么我们就把构造函数私有化,那么在派生类中就不能构造基类的对象。

如果在c++11中,提供了一个关键字final禁止继承

5、友元关系不能继承,也就是基类友元不能访问子类的私有和保护成员。

6、基类定义了一个static静态成员,那么不管有多少个子类,大家都共享这个静态成员。

7、在继承中构成多态的两个条件

  • 调用函数的对象必须是指针或者引用。
  • 被调用的函数必须是虚函数,且完成了虚函数的重写。

8、协变

  • 虚函数重写有一个例外:重写的虚函数的返回值可以不同,但是必须分别是基类指针和派生类指针或者基类引用和派生类引用。
class A{};
class B : public A {};

class Person {
public:
    virtual A* f() { return new A; }
};

class Student : public Person {
public:
    virtual B* f() { return new B; }
};

9、析构函数的重写问题

  • 基类中的析构函数如果是虚函数,那么派生类的析构函数就重写了基类的析构函数。这里他们的函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor,这也说明的基类的析构函数最好写成虚函数。

10、重载、重写(覆盖)、重定义(隐藏)

  • 重载:在同一作用域,函数名和参数列表必须相同
  • 重写:在基类和派生类的作用域中,函数名、参数列表、返回值必须相同(协变除外),两个函数必须为虚函数。
  • 重定义:在基类和派生类的作用域中,两个函数名相同,这两个函数不构成重写就构成重定义。

11、inline函数可以是虚函数吗? 不能,因为inline函数没有地址,无法把地址放到虚函数表中。
12、静态成员可以是虚函数吗? 不能,因为静态成员函数没有this指针,使用类型::成员函数的调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表。
13、构造函数可以是虚函数吗? 不能,因为对象中的虚函数表指针是在构造函数初始化列表阶段才初始化的。
14、析构函数可以是虚函数吗? 可以,并且最好把基类的析构函数定义成虚函数。

15、友元函数可以是虚函数吗? 不可以,因为友元函数不是类的成员函数。

猜你喜欢

转载自blog.csdn.net/qq_40421919/article/details/86644250