类成员对象中含有类对象的 构造器,拷贝构造器,赋值运算符重载的写法

通常情况一下,我们会认为一个类中如果不写任何的构造器,析构器,拷贝构造器,赋值运算符重载函数。我们认为他是空。写与不写如下如的结果是类同的。

如例:

class A
{
public:
	A(){}
	A(const A&){}
	A& operator=(const A&){ return *this;}
	~A(){}
};

但是当我们一个类中含有对像成员,能否我们认为还是空呢,默认的是不是跟空是等同的呢。 

测试构造器的代码:

class A
{
public:
	A(){cout<<"A constructor"<<endl;}
	A(const A&){cout<<"A copy constructor"<<endl;}
	A& operator=(const A&){ cout<<"A operator="<<endl;return *this;}
	~A(){cout<<"A destructor"<<endl;}
};
class B
{
public:
	B(){cout<<"B constructor"<<endl;}
public:
	A a;
};

int main()
{
	B b;
	return 0;
}

运行结果如下:

A constructor
B constructor
B destructor
A destructor

此时调用的默认无参构造器,如果A的构造器参数是非空的。则调用会出错。

示例如下:

class A
{
public:
	A(int){cout<<"A constructor"<<endl;}
	A(const A&){cout<<"A copy constructor"<<endl;}
	A& operator=(const A&){ cout<<"A operator="<<endl;return *this;}
	~A(){cout<<"A destructor"<<endl;}
};
class B
{
public:
	B(){cout<<"B constructor"<<endl;}

public:
	A a;
};

int main()
{
	B b;
	return 0;
}
运行结果如下:

g++ -O0 -g3 -Wall -c -fmessage-length=0 -o src\test.o ..\src\test.cpp
..\src\test.cpp: In constructor 'B::B()':
..\src\test.cpp:15:5: error: no matching function for call to 'A::A()'
..\src\test.cpp:15:5: note: candidates are:
..\src\test.cpp:8:2: note: A::A(const A&)
..\src\test.cpp:8:2: note:   candidate expects 1 argument, 0 provided
..\src\test.cpp:7:2: note: A::A(int)
..\src\test.cpp:7:2: note:   candidate expects 1 argument, 0 provided
..\src\test.cpp: In copy constructor 'B::B(const B&)':
..\src\test.cpp:16:13: error: no matching function for call to 'A::A()'
..\src\test.cpp:16:13: note: candidates are:
..\src\test.cpp:8:2: note: A::A(const A&)
..\src\test.cpp:8:2: note:   candidate expects 1 argument, 0 provided
..\src\test.cpp:7:2: note: A::A(int)
..\src\test.cpp:7:2: note:   candidate expects 1 argument, 0 provided
Build error occurred, build is stopped

如保来改正的,如果显示的写含有参数的构造器,内容不再是空,包含对成员对象的初始化。

示例如下:

class A
{
public:
	A(int){cout<<"A constructor with int"<<endl;}
	A(const A&){cout<<"A copy constructor"<<endl;}
	A& operator=(const A&){ cout<<"A operator="<<endl;return *this;}
	~A(){cout<<"A destructor"<<endl;}
};
class B
{
public:
	B():a(1){cout<<"B constructor"<<endl;}

public:
	A a;
};

int main()
{
	B b;
	return 0;
}

《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《

测试拷贝构造函数

class A
{
public:
	A(int){cout<<"A constructor with int"<<endl;}
	A(const A&){cout<<"A copy constructor"<<endl;}
	A& operator=(const A&){ cout<<"A operator="<<endl;return *this;}
	~A(){cout<<"A destructor"<<endl;}
};
class B
{
public:
	B():a(1){cout<<"B constructor"<<endl;}
	B(const B& b){cout<<"B copy constructor"<<endl;}

public:
	A a;
};

int main()
{
	B b;
	return 0;
}

编译结果

g++ -O0 -g3 -Wall -c -fmessage-length=0 -o src\test.o ..\src\test.cpp
..\src\test.cpp: In copy constructor 'B::B(const B&)':
..\src\test.cpp:16:15: error: no matching function for call to 'A::A()'
..\src\test.cpp:16:15: note: candidates are:
..\src\test.cpp:8:2: note: A::A(const A&)
..\src\test.cpp:8:2: note:   candidate expects 1 argument, 0 provided
..\src\test.cpp:7:2: note: A::A(int)
..\src\test.cpp:7:2: note:   candidate expects 1 argument, 0 provided
Build error occurred, build is stopped

改正如下:

class A
{
public:
	A(int){cout<<"A constructor with int"<<endl;}
	A(const A&){cout<<"A copy constructor"<<endl;}
	A& operator=(const A&){ cout<<"A operator="<<endl;return *this;}
	~A(){cout<<"A destructor"<<endl;}
};
class B
{
public:
	B():a(1){cout<<"B constructor"<<endl;}
	B(const B& b):a(b.a){cout<<"B copy constructor"<<endl;}


public:
	A a;
};

int main()
{
	B b;
	return 0;
}
《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《
同理赋值运算符重载正确如下:

class A
{
public:
	A(int){cout<<"A constructor with int"<<endl;}
	A(const A&){cout<<"A copy constructor"<<endl;}
	A& operator=(const A&){ cout<<"A operator="<<endl;return *this;}
	~A(){cout<<"A destructor"<<endl;}
};
class B
{
public:
	B():a(1){cout<<"B constructor"<<endl;}
	B(const B& b):a(b.a){cout<<"B copy constructor"<<endl;}
	B& operator=(const B&b){ a = b.a;cout<<"B operBtor="<<endl;return *this;}
//	~B(){cout<<"B destructor"<<endl;}

public:
	A a;
};

int main()
{
	B b;
	return 0;
}

综上,含有类成员对象的类构造器,拷贝构造器,赋值运算符重载函数。如果采用默认,应用时调用关系是正确的,但是缺陷是浅拷贝(shallow copy )。所以如果需要重写,不能单纯认为是空。要显示的调用成员对象的的类构造器,拷贝构造器,赋值运算符重载函数。不然用空的函数覆盖了默认,后果不堪设想。

如下:

class A
{
public:
	A(){cout<<"A constructor "<<endl;}
	A(const A&){cout<<"A copy constructor"<<endl;}
	A& operator=(const A&){ cout<<"A operator="<<endl;return *this;}
	~A(){cout<<"A destructor"<<endl;}
};
class B
{
public:
	B():a(){cout<<"B constructor"<<endl;}
	B(const B& b){cout<<"B copy constructor"<<endl;}
//	B(const B& b):a(b.a){cout<<"B copy constructor"<<endl;}
	B& operator=(const B&b){ a = b.a;cout<<"B operBtor="<<endl;return *this;}
	~B(){cout<<"B destructor"<<endl;}

public:
	A a;
};

void func(B b)
{

}
int main()
{
	B b;
	cout<<"------------"<<endl;
	func(b);
	cout<<"------------"<<endl;
	return 0;
}


运行结果

A constructor 
B constructor
------------
A constructor          //认真看,错误就在这里,这样跟本没有完成拷贝,而是默认构造了。
B copy constructor
B destructor
A destructor
------------
B destructor
A destructor

正确:

class A
{
public:
	A(){cout<<"A constructor "<<endl;}
	A(const A&){cout<<"A copy constructor"<<endl;}
	A& operator=(const A&){ cout<<"A operator="<<endl;return *this;}
	~A(){cout<<"A destructor"<<endl;}
};
class B
{
public:
	B():a(){cout<<"B constructor"<<endl;}
//	B(const B& b){cout<<"B copy constructor"<<endl;}
	B(const B& b):a(b.a){cout<<"B copy constructor"<<endl;}
	B& operator=(const B&b){ a = b.a;cout<<"B operBtor="<<endl;return *this;}
	~B(){cout<<"B destructor"<<endl;}

public:
	A a;
};

void func(B b)
{

}
int main()
{
	B b;
	cout<<"------------"<<endl;
	func(b);
	cout<<"------------"<<endl;
	return 0;
}

正确的运行结果:


A constructor 
B constructor
------------
A copy constructor                          //这才是正确的结果
B copy constructor
B destructor
A destructor
------------
B destructor
A destructor








  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

developer_wgl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值