目录
一、派生类构造函数的执行顺序
1.先调用基类构造函数
2.再执行派生类构造函数本身(即派生类构造函数的函数体)
#include<iostream>
using namespace std;
class A
{
public:
A()//定义基类构造函数
{
cout<<"A constructor"<<endl;
}
};
class B:public A//声明派生类B
{
public:
B()//定义派生类构造函数
{
cout<<"B constructor"<<endl;
}
};
int main()
{
B b;//因为派生类的对象要被创建,派生类是继承了基类,所以必须先初始化基类,接着再初始化派生类
return 0;
}
二、析构函数的调用顺序
1.调用派生类的析构函数
2.调用成员对象类的析构函数
3.调用基类的析构函数
#include<iostream>
using namespace std;
class point
{
public:
point()
{
cout<<"point构造"<<endl;
}
~point()
{
cout<<"point析构"<<endl;
}
};
class circle : public point
{
public:
circle()
{
cout<<"circle构造"<<endl;
}
~circle()
{
cout<<"circle析构"<<endl;
}
};
int main()
{
circle c;
}
三、基类的初始化
基类中的数据初始化只能在初始化列表中进行,而不能在函数体中用赋值语句来初始化
而在初始化表中进行的时候只能通过调用构造函数来进行,而不能通过赋值来初始化
#include<iostream>
using namespace std;
class point
{
int x,y;
public:
point(int a,int b)
{
x=a;
y=b;
cout<<"point"<<endl;
}
int getx()
{
return x;
}
int gety()
{
return y;
}
};
class circle:public point
{
int r;
public:
circle(int a,int b,int c):point(a,b)//point(a,b)是初始化列表,
//circle()函数中有3个参数,前两个参数a,b是为了初始化派生类point,将circle()中的两个参数a和b,传递给后面point()中的a,b ,
//然后调用上面的构造函数
//第3个参数c是为了初始化自己
{
r=c;
cout<<"circle"<<endl;
}
double area()
{
return 3.14*r*r;
}
};
int main()
{
circle c(1,2,3);
cout<<c.getx()<<endl<<c.gety()<<endl;
cout<<c.area()<<endl;
return 0;
}
//代码举例2
#include<iostream>
using namespace std;
class point
{
int x,y;
public:
point(int a,int b)
{
x=a;
y=b;
cout<<"point"<<endl;
}
int getx()
{
return x;
}
int gety()
{
return y;
}
};
class circle:public point
{
int r;
public:
circle(int a,int b,int c) ;//此处只是声明构造函数
};
circle::circle(int a,int b,int c):point(a,b)//此处定义了circle的构造函数,并且调用了基类point的构造函数
{
r=c;
cout<<"circle"<<endl;
}
int main()
{
circle c(1,2,3);
cout<<c.getx()<<endl<<c.gety()<<endl;
return 0;
}
//circle::circle(int a,int b,int c):point(a,b)
//需要注意的是:冒号后面是对基类构造函数的调用,而不是声明,所以括号里的参数是实参,它们不但可以是派生类构造函数总参数表中的参数,还可以是局部变量、常量等
四、调用基类构造函数的两种方式
1.显式方式:在派生类的构造函数中,为基类的构造函数提供参数
派生类名(参数表):基类名(参数表2)
例如: circle(int a,int b,int c):point(a,b)
2.隐式方式:在派生类的构造函数中,省略基类构造函数时,派生类的构造函数则
五、多层派生的构造函数
每一层的派生类只会调用上一层的直接的构造函数。不关系任何其它的包括上层基类的构造函数
基类: class point
一级派生:class circle : public point
二级派生:class cylinder : public circle
#include<iostream>
using namespace std;
class point
{
int x,y;
public:
point(int a,int b)//第四步:当point初始化了,再执行circle的构造函数
{
x=a;
y=b;
cout<<"point"<<endl;
}
int getx()
{
return x;
}
int gety()
{
return y;
}
};
class circle : public point//因为circle类继承了point类,所以在初始化circle的时候必须通过初始化列表将circle的前两个参数a,b
//传递进来,然后调用上一层point类的构造函数,来初始化它
{
int r;
public: circle(int a,int b,int c):point(a,b)//第三步:而circle又继承了point,再将ciecle的前两个参数a,b,传递给point()中的a,b,
//然后调用上一层的point的构造函数,用来初始化point
{
r=c;cout<<"circle"<<endl;
}
double area()
{
return 3.14*r*r;
}
};
class cylinder : public circle
{
int h;
public: cylinder(int a,int b,int c,int d):circle(a,b,c)//第二步:因为cylinder继承了circle,将cylinder的前3个参数a,b,c传递给
//后面的circle()中的a,b,c,然后调用上一层的circle的构造函数,用来初始化circle
{
h=d;
cout<<"cylinder"<<endl;
}
double volume()
{
return area()*h;
}
};
int main()
{
cylinder cy(1,2,3,4);//第一步:调用cylinder的构造函数,并且将实参1,2,3,4分别传递给a,b,c,d
}
六、有子对象的派生类的构造函数
执行构造函数的顺序:
1. 父类的构造函数
2. 子对象的构造函数
3. 子类的构造函数
注意,按照子对象声明顺序构造 ,下面例子中,先输出子对象a的构造,再输出子对象b的构造
//例如
class Circle : public Point
{
A a;//此处是子对象的声明
B b;
int r;
public:
Circle(int a,int b,int c):Point(a,b),b(3),a(5)
基本框架
class A
{
};
class point
{
};
class circle : public point
{
public:
A a;//A是已声明的类名,a是A类的对象,a就是子对象
};
int main()
{
circle c;
}
//代码举例:
#include<iostream>
using namespace std;
class A
{
public:
A()
{
cout<<"A constructor"<<endl;
}
};
class point
{
int x,y;
public:
point(int a,int b)
{
x=a;
y=b;
cout<<"point"<<endl;
}
int getx()
{
return x;
}
int gety()
{
return y;
}
};
class circle : public point
{
A a;
int r;
public:
circle(int a,int b,int c):point(a,b)
{
r=c;
cout<<"circle"<<endl;
}
double area()
{
return 3.14*r*r;
}
};
int main()
{
circle c(1,2,3);
}
//有析构时
#include<iostream>
using namespace std;
class A{
public:
A()
{
cout<<"A constructor"<<endl;
}
~A()
{
cout<<"A 析构"<<endl;
}
};
class point
{
int x,y;
public:
point(int a,int b)
{
x=a;
y=b;
cout<<"point"<<endl;
}
~point()
{
cout<<"point 析构"<<endl;
}
int getx()
{
return x;
}
int gety()
{
return y;
}
};
class circle : public point
{
A a;
int r;
public:
circle(int a,int b,int c):point(a,b)
{
r=c;cout<<"circle"<<endl;
}
double area()
{
return 3.14*r*r;
}
~circle()
{
cout<<"circle 析构"<<endl;
}
};
int main()
{
circle c(1,2,3);
}
//子对象有参数
#include<iostream>
using namespace std;
class A
{
int x;
public:
A(int m)
{
x=m;
cout<<"A constructor"<<endl;
}
};
class Point
{
int x,y;
public:
Point(int a,int b)
{
x=a;
y=b;
cout<<"Point"<<endl;
}
int getx()
{
return x;
}
int gety()
{
return y;
}
};
class Circle : public Point
{
A a;
int r;
public:
Circle(int a,int b,int c):Point(a,b),a(5)//a(5)中的a表示对象
//circle继承了point,所以首先执行point的构造函数,然后执行子对象a的构造函数,子对象a后面有一个参数5,调用A类的构造函数,
{
r=c;
cout<<"Circle"<<endl;
}
double area()
{
return 3.14*r*r;
}
};
int main()
{
Circle ci(1,2,3);
}
//按照子对象声明顺序构造
#include<iostream>
using namespace std;
class A
{
int x;
public:A(int m)
{
x=m;
cout<<"A constructor"<<endl;
}
};
class B
{
int y;
public:B(int n)
{
y=n;
cout<<"B constructor"<<endl;
}
};
class Point
{
int x,y;
public:
Point(int a,int b)
{
x=a;
y=b;
cout<<"Point"<<endl;
}
int getx()
{
return x;
}
int gety()
{
return y;
}
};
class Circle : public Point
{
A a;//此处是子对象的声明
B b;
int r;
public:
Circle(int a,int b,int c):Point(a,b),b(3),a(5)
{
r=c;
cout<<"Circle"<<endl;
}
double area()
{
return 3.14*r*r;
}
};
int main()
{
Circle ci(1,2,3);
}