1 继承中的访问权限问题
- 所有继承方式, 子类都无法访问父类的private成员.
那么用如下测试代码尝试一下:
#include <iostream>
using namespace std;class father {
public:int m_father_public_value;
protected:int m_father_protected_value;
private:int m_father_private_value;
};class public_inherited_son : public father {
public:void public_inherited_son_visit_father_public_value() {cout << m_father_public_value << endl;}void public_inherited_son_visit_father_protected_value() {cout << m_father_protected_value << endl;}void public_inherited_son_visit_father_private_value() {cout << m_father_private_value << endl;}
};class protected_inherited_son: protected father {
public:void protected_inherited_son_visit_father_public_value() {cout << m_father_public_value << endl;}void protected_inherited_son_visit_father_protected_value() {cout << m_father_protected_value << endl;}void protected_inherited_son_visit_father_private_value() {cout << m_father_private_value << endl;}
};class private_inherited_son: private father {
public:void private_inherited_son_visit_father_public_value() {cout << m_father_public_value << endl;}void private_inherited_son_visit_father_protected_value() {cout << m_father_protected_value << endl;}void private_inherited_son_visit_father_private_value() {cout << m_father_private_value << endl;}
};int main() {return 0;
}
编译一下发现:
说明了子类不能访问父类的私有成员.
- public继承, 父类的public和protected成员还是子类的public和protected成员.
试着用public继承的子类实例化的对象类外访问父类的public和protected成员, 如下测试代码:
int main() {public_inherited_son public_inherited_son_instance1;cout << public_inherited_son_instance1.m_father_public_value << endl;cout << public_inherited_son_instance1.m_father_protected_value << endl;return 0;
}
编译发现:
说明public继承中父类的public和protected成员在子类中还是public和protected成员, 且protected成员在类外不能访问.
- protected继承, 父类的public和protected成员还是子类的protected成员.
试着用protected继承的子类实例化的对象类外访问父类的public和protected成员, 如下测试代码:
int main() {protected_inherited_son protected_inherited_son_instance1;cout << protected_inherited_son_instance1.m_father_public_value << endl;cout << protected_inherited_son_instance1.m_father_protected_value << endl;return 0;
}
编译发现:
父类的public和protected成员都不能在类外访问了, 说明都变成了protected成员.
- private继承, 父类的public和protected成员成为子类的private成员.
就不测试了...
2 继承后的子类和父类的析构顺序问题
当继承后的子类实例化对象之后, 其对象所占用的内存空间中会保留一份父类的对象空间. 所以子类实例化对象的过程中, 其父类的构造函数也会被调用, 析构过程同理.
用如下代码测试一下其发生顺序:
#include <iostream>
using namespace std;class father {
public:father() {cout << "calling father's constructor" << endl;}~father() {cout << "calling father's disconstructor" << endl;}
};class public_inherited_son : public father {
public:public_inherited_son() {cout << "calling son's constructor" << endl;}~public_inherited_son() {cout << "calling son's disconstructor" << endl;}
};int main() {public_inherited_son public_inherited_son_instance1;return 0;
}
结果为:
说明了子类实例化对象的过程中会先调用父类的构造函数, 然后是子类的构造函数. 同时也表明在栈上的话析构顺序相反.
那么在堆区呢?
用如下代码测试:
#include <iostream>
using namespace std;class father {
public:father() {cout << "calling father's constructor" << endl;}~father() {cout << "calling father's disconstructor" << endl;}
};class public_inherited_son : public father {
public:public_inherited_son() {cout << "calling son's constructor" << endl;}~public_inherited_son() {cout << "calling son's disconstructor" << endl;}
};int main() {public_inherited_son *p_public_inherited_son_instance1 = new public_inherited_son;delete p_public_inherited_son_instance1;return 0;
}
运行结果:
总结:
子类实例化对象的过程会先调用父类的构造函数, 然后是子类的构造函数. 析构函数的顺序会反过来, 无论是栈上还是堆上.
2.1 调用父类构造函数想要传递参数方式
前面说到, 子类实例化对象时默认先调用父类构造函数, 再调用子类构造函数, 如果想要在调用父类构造函数时传递参数, 就需要显示的调用父类构造函数, 即在子类构造函数初始化列表上显示调用父类构造函数并传递参数.
2.2 C++11调用父类构造函数新方法
3 父类子类的同名成员处理方法
如果想要在子类对象访问父类同名成员, 须在成员名前加上父类名称作用域, 如下:
#include <iostream>
using namespace std;class father {
public:int member_value;
};class public_inherited_son : public father {
public:int member_value;
};int main() {public_inherited_son public_inherited_son_instance1;public_inherited_son_instance1.member_value = 10;public_inherited_son_instance1.father::member_value = 1;cout << public_inherited_son_instance1.member_value << endl;cout << public_inherited_son_instance1.father::member_value << endl;return 0;
}
结果如下:
需注意: 如果子类中存在同名成员函数, 子类成员函数会隐藏掉父类中所有的同名成员函数(包括所有的重载函数), 如以下测试代码:
#include <iostream>
using namespace std;class father {
public:void func1(int arg1) {cout << arg1 << endl;}void func1(int arg1, int arg2) {cout << arg1 << arg2 << endl;}
};class public_inherited_son : public father {
public:void func1(int arg1, int arg2, int arg3) {cout << arg1 << arg2 << arg3 << endl;}
};int main() {public_inherited_son public_inherited_son_instance1;public_inherited_son_instance1.func1(1);public_inherited_son_instance1.func1(1, 2);return 0;
}
编译发现:
如果想要使用父类函数的话, 需要加上父类作用域, 如下:
#include <iostream>
using namespace std;class father {
public:void func1(int arg1) {cout << arg1 << endl;}void func1(int arg1, int arg2) {cout << arg1 << arg2 << endl;}
};class public_inherited_son : public father {
public:void func1(int arg1, int arg2, int arg3) {cout << arg1 << arg2 << arg3 << endl;}
};int main() {public_inherited_son public_inherited_son_instance1;public_inherited_son_instance1.father::func1(1);public_inherited_son_instance1.father::func1(1, 2);return 0;
}
结果为: