1、类的数据成员是类对象
对一个类的对象成员进行初始化
#include<iostream>
using namespace std;
class lei1
{
private:
int xx;
public:
lei1(int dt){
xx=dt;
}
void disp(){
cout<<"class lei1 private data is:"<<xx<<endl;
}
};
class lei2
{
private:
int yy;
lei1 p;
lei1 q;
public:
lei2(int dt);
void disp(){
cout<<"class lei2 private data is:"<<yy<<endl;
}
void get_lei1_p(){
p.disp();
}
void get_lei1_q(){
q.disp();
}
};
lei2::lei2(int z):p(10),q(-10),yy(z)
{
}
int main()
{
lei2 a(20);
a.get_lei1_p();
a.get_lei1_q();
a.disp();
}
上面程序的初始化语句有两种写法:
lei2::lei2(int dt):p(10),q(-10)
{
yy=dt;
}
//或者跟上述程序的写法相同
lei2::lei2(int dt):p(10),q(-10),yy(dt)
{
}

对类中对象成员的初始化需要在构造函数头部的后面用冒号隔开后给出,冒号后面的部分被称为初始化列表。
类对象的初始化还可以通过函数的参数传递来实现。
#include<iostream>
using namespace std;
class lei1
{
private:
int xx;
public:
lei1(int dt){
xx=dt;
}
void disp(){
cout<<xx<<endl;
}
};
class lei2
{
private:
int yy;
lei1 a;
lei1 b;
public:
lei2(int,int,int);
void printf_lei1_a(){
a.disp();
}
void printf_lei1_b(){
b.disp();
}
void disp(){
cout<<yy<<endl;
}
};
lei2::lei2(int x,int y,int z):a(x),b(y),yy(z)
{
}
int main()
{
lei2 dt(10,20,30);
dt.printf_lei1_a();
dt.printf_lei1_b();
dt.disp();
}
注意:当用函数参数初始化类的对象时,应该保持构造函数的参数数量一致,否则会导致编译出错
lei2(int,int,int);

当类的成员中包含对象时,其构造函数和析构函数的执行是有顺序的。
#include<iostream>
using namespace std;
class ina
{
public:
ina(){
cout<<"entering ina constructor!"<<endl;
}
~ina(){
cout<<"entering ina destructor!"<<endl;
}
};
class inb
{
public:
inb(){
cout<<"entering inb constructor!"<<endl;
}
~inb(){
cout<<"entering inb destructor!"<<endl;
}
};
class outc
{
private:
ina a1;
ina a2;
inb b1;
inb b2;
public:
outc(){
cout<<"entering outc constructor!"<<endl;
}
~outc(){
cout<<"entering outc destructor!"<<endl;
}
};
int main()
{
outc x;
}
对于构造函数来讲,首先调用内嵌成员对象的构造函数。本程序是采用默认构造函数来初始化每个内嵌对象的。
构造函数的调用顺序与初始化列表中的顺序没有关系。
对于析构函数来讲,其调用顺序与构造函数正好相反。

要想改变调用的顺序:
class outc
{
private:
inb b1;
inb b2;
ina a1;
ina a2;
public:
outc(){
cout<<"entering outc constructor!"<<endl;
}
~outc(){
cout<<"entering outc destructor!"<<endl;
}
};

2、类的数据成员是常量
#include<iostream>
using namespace std;
class xint
{
public:
const int dt1;
const double dt2;
int dt3;
public:
xint():dt1(10),dt2(3.14)
{
dt3=20;
}
};
int main()
{
xint x;
cout<<"dt1="<<x.dt1<<endl;
cout<<"dt2="<<x.dt2<<endl;
cout<<"dt3="<<x.dt3<<endl;
}
类的数据成员是常量,在本程序中,常量是dt1和dt2,注意他们属于类的public,否则会无法访问,编译出错。
在类中定义的常量的值不能直接在后面利用等号给出,如:
const int dt1=10;
const double dt2=3.14;
这样是不行的,必须通过构造函数进行设置。
还有以下几种方式都是可以的:
【方式1】
#include<iostream>
using namespace std;
class xint
{
public:
const int dt1;
const double dt2;
int dt3;
public:
xint(int a,double b):dt1(a),dt2(b)
{
dt3=20;
}
};
int main()
{
xint x(10,3.14);
cout<<"dt1="<<x.dt1<<endl;
cout<<"dt2="<<x.dt2<<endl;
cout<<"dt3="<<x.dt3<<endl;
}
【方式2】
#include<iostream>
using namespace std;
class xint
{
public:
const int dt1;
const double dt2;
int dt3;
public:
xint(int a,double b,int c):dt1(a),dt2(b),dt3(c)
{
}
};
int main()
{
xint x(10,3.14,20);
cout<<"dt1="<<x.dt1<<endl;
cout<<"dt2="<<x.dt2<<endl;
cout<<"dt3="<<x.dt3<<endl;
}
【方式3】
#include<iostream>
using namespace std;
class xint
{
public:
const int dt1;
const double dt2;
int dt3;
public:
xint(int a,double b):dt1(a),dt2(b),dt3(20)
{
}
};
int main()
{
xint x(10,3.14);
cout<<"dt1="<<x.dt1<<endl;
cout<<"dt2="<<x.dt2<<endl;
cout<<"dt3="<<x.dt3<<endl;
}
当类中有const数据成员定义时,该类的对象之间是不能互相赋值的,如:
xint x(10.3.14),y(20,6.18);
x=y;
const数据成员的值是不能改变的,所以这样写是错误的。
要是想要实现const数据成员之间能够相互赋值该怎么操作呢?
这就需要用到运算符的重载
#include<iostream>
using namespace std;
class xint
{
int x;
const int y;
public:
xint(int a,int b):y(b)
{
x=a;
}
xint &operator=(xint &dt)
{
x=dt.x;
return *this;
}
void disp()
{
cout<<"x="<<x<<'\t'<<"y="<<y<<endl;
}
};
int main()
{
xint p(10,100),q(20,200);
p.disp();
q.disp();
p=q;
p.disp();
}
其中
xint &operator=(xint &dt)
{
x=dt.x;
return *this;
}
也可以改写为
void &operator=(xint &dt)
{
x=dt.x;
}
但是这样写的话,不能实现连等操作。

本文详细解析了C++中类成员的初始化过程,包括如何在构造函数中初始化对象成员和常量成员,以及构造函数和析构函数的调用顺序。通过实例演示了初始化列表的使用,以及如何正确初始化const数据成员。

521

被折叠的 条评论
为什么被折叠?



