1. 类中的const 成员函数,无论在声明还是在定义中都需要指定为const,因为存在基于const与非const的重载,所以当定义无const是,将视其为非const版本的定义:
class A { public: void f() const; }; void A::f() const { } |
2. 在子类的初始化列表中初始化父类成员是只能通过父类的构造函数(和复制构造函数),不能直接初始化:
class A { int i; public: A(int j):i(j) {} A(const A&a):i(a.i) {} }; | class B:A { int j; public: B(int x, int y): A(x), j(y) {} B(const B &b):A(b), j(b.j) {} }; |
3. 在创建子类对象时会创建父类对象,在调用子类构造函数时会调用父类构造函数,此时如果父类没有无参构造函数,则必须在子类构造函数初始化列表中显示调用父类的构造函数,否则报错:
class A { int i; public: A(int j):i(j) {} A(const A&a):i(a.i) {} }; | class B:A { int j; public: B(int x, int y): j(y) {} // 报错 B(const B &b):j(b.j) {} // 报错 }; |
4. virtual 不能与 static 一起使用,静态函数不存在动态绑定;同时不能用静态函数去重写父类中的虚函数
5. 注意分清重写、重载与覆盖,当子类函数与父类函数名字相同时,什么时候是重写父类的虚函数,什么时候是重载父类的函数,什么时候又是覆盖了父类的函数:
a. 当子类函数与父类(虚)函数有不同的标识(函数名、参数即const限定符)时,为重载;
b. 当子类函数与父类的非虚函数有相同标识时,为覆盖;
c. 当子类函数与父类的虚函数有相同标识和相同返回类型(或都为对自身类型的引用)时,为重写,此时用父类应用调用时会发生动态绑定;
d. 当子类函数与父类的虚函数有相同标识,但返回类型不同时,会出现编译错误