/* 一些类的辅助知识
【 继承与派生 】
B是A: class B: public A {...}
* B中函数不可访问A的private成员,可访问protect成员;
* 在B中访问A中同名成员时,需使用‘::’, Eg. A::method1
* 创建B对象时会先调用A中构造函数,后调用B的构造函数。对象销毁时顺序相反。
* 定义B的构造函数:
class A{
private:
int i, j;
public:
A(int n1, int n2): i(n1), j(n2){};
...
};
class B: public A {
private:
int k;
public:
B(int n1, int n2, int n3): A(n1, n2), k(n3){};
...
};
* public赋值兼容规则:
派生类对象可赋值给基类对象(反过来不可):
Eg. base b; derived d;
b = d; base &b = d; base *b = &d;
(如果派生方式不是public,则此规则不成立)
* /
【 虚函数 】
Eg. virtual int get(), 可参与多态
* 构造函数和静态成员函数不可为虚函数
* 【多态/Polymorphism】
当通过一个基类指针或引用调用基类和派生类同名虚函数时:
若该指针/引用指向一个某个派生类对象,则被调用的是该派生类的虚函数(一个派生类指针赋值给一个基类指针);
若指向/引用一个基类对象,则调用的是基类的虚函数。
(若基类指针调用非虚函数,则被调用的只能是积累中该函数)
class Base {
public:
void print1() {
cout << "This is a print from Base class" << endl;
}
void virtual print2() {
cout << "This is a virtual print from Base class" << endl;
}
};
class Derived: public Base{
public:
void print1() {
cout << "This is a print from Derived class" << endl;
}
void virtual print2() {
cout << "This is a virtual print from Derived class" << endl;
}
};
int main() {
Base b;
Derived d;
Base *b1 = &d;
Base &b2 = d;
b.print1();
b.print2();
b1->print1();
b1->print2();
b2.print1();
b2.print2();
}
输出:
This is a print from Base class
This is a virtual print from Base class
This is a print from Base class
This is a virtual print from Derived class
This is a print from Base class
This is a virtual print from Derived class
#作用: 提高程序的可扩充性;
#实现原理:
每一个有虚函数的类及其派生的类都会有一个虚函数表,表中存放着该类每个虚函数对应的指针。该类在生成对象时,会生成一个指向其虚函数表地址的指针(空间开销会多四个字节)。多态的实现,就是根据基类指针指向的对象中包含的这个指针指向的虚函数表找到相应的虚函数。->使用多太缺点:增加额外的时间和空间开销
若某基类虚函数没有被派生类重载,则此派生类虚函数表中会保存基类的虚函数地址。
class Base { class Derived: public Base {
int i; int j;
virtual method1() {...} virtual method1() {...}
virtual method2() {...} ...
...
} }
Base b;
Derived d;
Base *p = d;
* 虚析构函数
如果一个类中有虚函数,建议将析构函数也定义为虚函数,则可保证用基类指针指向派生类时,函数删除此指针可先调动派生类析构,再调用基类析构函数。
& 构造函数不可定义为虚构函数
* 纯虚函数:virtual void PrintInfo() = 0 (无函数体)
包含纯虚函数的类为抽象类。
a. 抽象类只能做为基类;
b. 不能创建对象,只可以通过指针或引用指向派生类对象
c. 抽象类中,普通成员函数可以调用纯虚函数;构造函数和析构函数不可调用
d. 一个类派生与一个抽象类,只有实现了所有基类中纯虚函数才可变为非抽象类