C++中的拷贝构造,赋值构造的形式如下:
eg:
A (A &a) {
this->x = a.x;
this->y = a.y;
cout << "这是一个拷贝构造函数" << endl;
}
A(const A &a) {
this->x = a.x;
this->y = a.y;
cout << "这是一个拷贝构造函数" << endl;
}
A &operator = (const A &a) {
this->x = a.x;
this->y = a.y;
cout << "这是一个赋值构造函数" << endl;
}
对象以值传递方式从函数返回时,若接受返回值的对象已经初始化过,则会调用赋值构造函数,且该对象还会调用析构函数,当对象中包含指针时,会使该指针失效,因此需要重载赋值构造函数,使用类似深拷贝或移动构造函数的方法赋值,才能避免指针失效。
拷贝构造测试
#include<bits/stdc++.h>
using namespace std;
class A {
public:
int *x;
int y;
A();
A (A &a) {
this->x = a.x;
this->y = a.y;
cout << "这是一个拷贝构造函数" << endl;
}
A(const A &a) {
this->x = a.x;
this->y = a.y;
cout << "这是一个使用了const的拷贝构造函数" << endl;
}
A &operator = (const A &a) {
this->x = a.x;
this->y = a.y;
cout << "这是一个赋值构造函数" << endl;
}
A (int t) {
x = new int(0);
y = t;
printf("address: %x, point:%x, val: %d\n", this, x, y );
}
~A() {
printf("delete %x\n", this);
}
};
void func(A ret) {
printf ("传值:stack address: %x, point: %x, value: %d\n", &ret, ret.x, ret.y);
}
A get() {
A ret(3);
printf ("从函数返回时stack address: %x, point: %x, value: %d\n", &ret, ret.x, ret.y);
return ret;
}
int main() {
A a(1);
A c = a;
printf ("C的:global address: %x, point: %x, value: %d\n", &c, c.x, c.y);
func(c);
A d = get();
printf ("D的:global address: %x, point: %x, value: %d\n", &d, d.x, d.y);
return 0;
}
测试结果
address: 89fed0, point:fb1698, val: 1
这是一个拷贝构造函数
C的:global address: 89fed8, point: fb1698, value: 1
这是一个拷贝构造函数
传值:stack address: 89fee0, point: fb1698, value: 1
delete 89fee0
address: 89fee8, point:fb1798, val: 3
从函数返回时stack address: 89fee8, point: fb1798, value: 3
D的:global address: 89fee8, point: fb1798, value: 3
delete 89fee8
delete 89fed8
delete 89fed0
赋值构造测试
#include<bits/stdc++.h>
using namespace std;
class A {
public:
int *x;
int y;
A() = default;
// A (const A &a) {
// this->x = a.x;
// this->y = a.y;
// cout << "这是一个const赋值构造函数" << endl;
// }
A &operator = (const A &a) {
this->x = a.x;
this->y = a.y;
cout << "这是一个赋值构造函数" << endl;
}
A (int t) {
x = new int(0);
y = t;
printf("address: %x, point:%x, val: %d\n", this, x, y );
}
~A() {
printf("delete %x\n", this);
}
};
void func(A ret) {
printf ("传值:stack address: %x, point: %x, value: %d\n", &ret, ret.x, ret.y);
}
A f () {
A ret (3);
printf ("stack address: %x, point: %x, value: %d\n", &ret, ret.x, ret.y);
return ret;
}
int main() {
A c;
c = f();
printf ("global address: %x, point: %x, value: %d\n", &c, c.x, c.y);
A a(1);
A d = a;
printf ("global address: %x, point: %x, value: %d\n", &d, d.x, d.y);
return 0;
}
测试结果
address: 89fee8, point:f51788, val: 3
stack address: 89fee8, point: f51788, value: 3
这是一个赋值构造函数
delete 89fee8
global address: 89fed8, point: f51788, value: 3
address: 89fee0, point:f51698, val: 1
global address: 89fee8, point: f51698, value: 1
delete 89fee8
delete 89fee0
delete 89fed8
C++中拷贝赋值函数的形参能否进行值传递?
形参进行值传递:
A( A);
不能。如果是这种情况下,调用拷贝构造函数的时候,首先要将实参传递给形参,这个传递的时候又要调用拷贝构造函数。。如此循环,无法完成拷贝,栈也会满。(俗称套娃)