目录
1.构造函数与析构函数调用顺序
无其它类对象时:
#include<iostream>
using namespace std;
class MyBase1
{
public:
MyBase1() { cout << "…BaseClass1 Object is created!" << endl; }//1
~MyBase1() { cout << "…BaseClass1 Object is destroyed!" << endl; }//2
};
class MyDerived1 : public MyBase1
{
public:
MyDerived1(){cout << "…First layer derived Object is created!" << endl;}//3
~MyDerived1(){cout << "…First layer derived Object is Destroyed!" << endl;}//4
};
class MyDerived11 : public MyDerived1
{
public:
MyDerived11(){cout << "…Second layer derived Object is created!" << endl;}//5
~MyDerived11(){cout << "…Second layer derived Object is destroyed!" << endl;}//6
};
int main()
{
MyBase1 a;
MyDerived1 b;
MyDerived11 c;
//函数调用顺序1 13 135 642 42 2
return 0;
}
构造函数执行顺序:基类构造函数->派生类构造函数
析构函数执行顺序与构造函数相反
有其它类对象时:
#include<iostream>
using namespace std;
class MyBase1
{
public:
MyBase1() { cout << "…BaseClass1 Object is created!" << endl; }//1
~MyBase1() { cout << "…BaseClass1 Object is destroyed!" << endl; }//2
};
class MyBase2
{
MyBase1 a1;
public:
MyBase2(){cout << "…BaseClass2 Object is created!" << endl;}//3
~MyBase2(){cout << "…BaseClass2 Object is destroyed!" << endl;}//4
};
class MyDerived1 : public MyBase2 {
MyBase1 a1;
public:
MyDerived1(){cout << "…First layer derived Object is created!" << endl;}//5
~MyDerived1(){cout << "…First layer derived Object is Destroyed!" << endl;}//6
};
class MyDerived11 : public MyDerived1 {
public:
MyDerived11(){cout << "…Second layer derived Object is created!" << endl;}//7
~MyDerived11(){cout << "…Second layer derived Object is destroyed!" << endl;}//8
};
int main()
{
MyBase2 a;
MyDerived1 b;
MyDerived11 c;
//函数调用顺序13 1315 13157 86242 6242 42
return 0;
}
构造函数执行顺序与无其它类对象基本相同,要注意:
先执行继承部分,再执行类中对象的创建,最后才是该类的构造函数
析构函数执行顺序与构造函数相反
代码中有标注调用顺序,可以自己运行看一下
2.类继承初始化理解
(1)初始化成员列表举例
#include<iostream>
using namespace std;
class MyBase31 {
int a, b, c;
public:
MyBase31(int x, int y, int z) :a(x), b(y), c(z)
{
cout << "…BaseClass31 Object is created!" << endl;
cout << a << " " << b << " " << c << endl;
}
~MyBase31() { cout << "…BaseClass31 Object is destroyed!" << endl; }
};
class MyBase32 {
int a, b, c;
public:
MyBase32(int x, int y, int z)
{
cout << "…BaseClass32 Object is created!" << endl;
cout << a << " " << b << " " << c << endl;
a = x, b = y, c = z;
cout << a << " " << b << " " << c << endl;
}
~MyBase32() { cout << "…BaseClass32 Object is destroyed!" << endl; }
};
int main()
{
MyBase31 a(1, 2, 3);
MyBase32 b(4, 5, 6);
return 0;
}
(2)相关易错分析
#include<iostream>
using namespace std;
class MyBase31 {
int a, b, c;
public:
MyBase31(int x, int y, int z) :a(x), b(y), c(z)
{
cout << "…BaseClass31 Object is created!" << endl;
cout << a << " " << b << " " << c << endl;
}
~MyBase31() { cout << "…BaseClass31 Object is destroyed!" << endl; }
};
class MyDerived1 : public MyBase31
{
MyBase31 a(5, 6, 7);// 问题1
int c;
public:
MyDerived1(int x) : c(x), MyBase31 (x, 8, 9)
{
cout << "…Base Object has been created!" << endl;
cout << "…Member Object has been created! " << a.x << " " << a.y << " "<< a.z << endl;//问题2
cout << "…Derived Object is created! " << c << endl;
}
};
int main()
{
MyDerived1 b(88);
return 0;
}
显示编译错误,
错误一:在类中不可以直接进行初始化
错误二:不可以直接调用私有变量
更改后:
#include<iostream>
using namespace std;
class MyBase31 {
int a, b, c;
public:
MyBase31(int x, int y, int z) :a(x), b(y), c(z)
{
cout << "…BaseClass31 Object is created!" << endl;//1
cout << a << " " << b << " " << c << endl;//1'
}
MyBase31()
{
cout << "…BaseClass31 Object is created! 123" << endl;//2
}
~MyBase31() { cout << "…BaseClass31 Object is destroyed!" << endl; }//3
};
class MyDerived1 : public MyBase31
{
MyBase31 a;
int c;
public:
MyDerived1(int x) : c(x), MyBase31 (x, 8, 9)
{
cout << "…Base Object has been created!" << endl;//4
cout << "…Derived Object is created! " << c << endl;//4'
}
};
int main()
{
MyDerived1 b(88);
return 0;
}
//函数调用顺序:11' 2 44' 3 3
此时可以正常输出结果:
构造函数执行顺序:
基类成员对象初始化->基类构造函数->派生类成员对象初始化->派生类构造函数
析构函数执行顺序与构造函数相反
3.不同继承方式对象的可见性
(1)public
#include<iostream>
using namespace std;
class MyBase3 {
int x;
void fun1() { cout <<"MyBase3-- - fun1()" << endl; }
protected:
int y;
void fun2() { cout << "MyBase3-- - fun2()" << endl; }
public:
int z;
MyBase3(int a, int b, int c) { x = a; y = b; z = c; }
MyBase3(){}
int getX() { cout << "MyBase3-- - x:" << endl; return x; }
int getY() { cout <<"MyBase3-- - y:" << endl; return y; }
int getZ() { cout << "MyBase3-- - z:" << endl; return z; }
void fun3() { cout << "MyBase3-- - fun3()" << endl; }
};
class MyDerived1 : public MyBase3 {
int p;
public:
MyDerived1(int a) : p(a), MyBase3() {};
int getP() { cout << "MyDerived-- - p:" << endl; return p; }
int disply()
{
cout << p << " " << x << " " << y << " " << z << " " << endl;//问题一
fun1(); //问题二
cout << endl;
fun2();
cout << endl;
fun3();
cout<< endl;
}
};
int main()
{
MyDerived1 a(3);
a.disply();
cout << a.x << " " << a.p << " " << a.y << " " << a.z << endl;//问题三
cout << a.getX() << " " << a.getP() << " " << a.getY() << " " << a.getZ() <<endl;
}
编译错误:
问题一:x是基类私有变量,不能访问
问题二:fun1()是私有成员函数,不能调用
问题三:x是基类私有变量,不能访问;
p是派生类私有变量,不能访问;
y是protected中变量,只有在派生类中才可以通过派生类对象访问基类的protected成员。
(2)private
#include<iostream>
using namespace std;
class MyBase3 {
int x;
void fun1() { cout <<"MyBase3-- - fun1()" << endl; }
protected:
int y;
void fun2() { cout << "MyBase3-- - fun2()" << endl; }
public:
int z;
MyBase3(int a, int b, int c) { x = a; y = b; z = c; }
MyBase3(){}
int getX() { cout << "MyBase3-- - x:" << endl; return x; }
int getY() { cout <<"MyBase3-- - y:" << endl; return y; }
int getZ() { cout << "MyBase3-- - z:" << endl; return z; }
void fun3() { cout << "MyBase3-- - fun3()" << endl; }
};
class MyDerived2 : private MyBase3 {
int p;
public:
MyDerived2(int a) : p(a), MyBase3() {};
MyDerived2() {}
int getP() { cout << "MyDerived---p:" << endl; return p; }
int disply()
{
cout << p << " " << x << " " << y << " " << z << " " << endl;//问题一
fun1(); //问题二
cout << endl;
fun2();
cout << endl;
fun3();
cout << endl;
}
};
class MyDerived21 : public MyDerived2
{
int p;
public:
MyDerived21(int a) : p(a), MyDerived2(){}
int getP() { cout << "MyDerived21---p:" << endl; return p; }
int disply1()
{
cout << p << " " << x << " " << y << " " << z << " " << endl;//问题三
}
};
int main(){
MyDerived2 a(3);
MyDerived21 b(6);
a.disply();
cout << a.x << " " << a.p << " " << a.y << " " << a.z << endl;//问题四
cout << a.getX() << " " << a.getP() << " " << a.getY() << " " << a.getZ() <<endl;//问题五
b.disply1();
}
显示编译错误:
问题一:x是基类私有变量,不能访问
问题二:fun1()是私有成员函数,不能调用
问题三:x是基类私有变量,不能访问;
MyDerived2对MyBase3是私有继承,MyBase3中成员全为私有成员,不可访问
所以y,z均报错
问题四:以上均可理解为私有变量,不可访问
问题五:a中的报错的成员函数由于是私有继承,均不可调用
(3)protected:
#include<iostream>
using namespace std;
class MyBase3 {
int x;
void fun1() { cout <<"MyBase3-- - fun1()" << endl; }
protected:
int y;
void fun2() { cout << "MyBase3-- - fun2()" << endl; }
public:
int z;
MyBase3(int a, int b, int c) { x = a; y = b; z = c; }
MyBase3(){}
int getX() { cout << "MyBase3-- - x:" << endl; return x; }
int getY() { cout <<"MyBase3-- - y:" << endl; return y; }
int getZ() { cout << "MyBase3-- - z:" << endl; return z; }
void fun3() { cout << "MyBase3-- - fun3()" << endl; }
};
class MyDerived3 : protected MyBase3
{
int p;
public:
MyDerived3(int a) : p(a),MyBase3(){}
MyDerived3(){}
int getP() { cout << "MyDerived---p:" << endl; return p; }
int disply()
{
cout << p << " " << x << " " << y << " " << z << " " << endl;//问题一
fun1(); //问题二
cout << endl;
fun2();
cout << endl;
fun3();
cout << endl;
}
};
class MyDerived31 : public MyDerived3 {
int p;
public:
MyDerived31(int a) : p(a),MyDerived3(){}
int getP() { cout << "MyDerived31---p:" << endl; return p; }
int disply1()
{
cout << p << " " << x << " " << y << " " << z << " " << endl;//问题三
}
};
int main()
{
MyDerived3 a(3);
MyDerived31 b(6);
a.disply();
cout << a.x << " " << a.p << " " << a.y << " " << a.z << endl;//问题四
cout << a.getX() << " " << a.getP() << " " << a.getY() << " " << a.getZ() <<endl;//问题五
b.disply1();
}
问题一:x是基类私有变量,不能访问
问题二:fun1()是私有成员函数,不能调用
问题三:x是基类私有变量,不能访问;
问题四:只有在派生类中才可以通过派生类对象访问基类的protected成员。
问题五:只有在派生类中才可以通过派生类对象访问基类的protected成员。
(4)重写基类的函数调用规则:
class MyBase {
public:
void f1() { cout << "…MyBase f1-----! 1" << endl; }//1
void f2() { cout << "…MyBase f2-----! 2" << endl; }//2
};
class MyDerived : public MyBase {
public:
void f2() { cout << "…MyDerived f2-----! 3" << endl; }//3
void f22() { MyBase::f2(); cout << "…MyDerived f2-----! 4" << endl; }//4
void f3() { cout << "…MyDerived f3-----! 5" << endl; }//5
};
int main()
{
MyDerived a;
a.f1(); cout << endl;
a.f2(); cout << endl;
a.f3(); cout << endl;
a.f22();
}
只要在派生类中重写基类的函数(函数名相同,参数不一定相同),就无法调用基类的相关函数,此时基类中的函数需要“基类::函数名”来调用