赋值运算符和复制建构子运算符有什么区别?

我不明白在 C + + 中赋值构造函数和复制建构子之间的区别,是这样的:

class A {
public:
A() {
cout << "A::A()" << endl;
}
};


// The copy constructor
A a = b;


// The assignment constructor
A c;
c = a;


// Is it right?

我想知道如何分配赋值构造函数和复制建构子的内存?

109301 次浏览

第一个是拷贝初始化,第二个是赋值,没有赋值构造函数这种东西。

A aa=bb;

使用编译器生成的复制建构子。

A cc;
cc=aa;

使用缺省构造函数构造 cc,然后在已存在的对象上使用 * 赋值运算符 * * (operator =)。

我想知道如何分配赋值构造函数和复制建构子的内存?

在这种情况下分配内存是什么意思,如果你想看看会发生什么,你可以:

class A
{
public :
A(){ cout<<"default constructor"<<endl;};
A(const A& other){ cout<<"copy constructor"<<endl;};
A& operator = (const A& other){cout <<"assignment operator"<<endl;}
};

我还建议你看看:

为什么要调用复制建构子而不是转换构造函数?

三的法则是什么?

复制建构子用于从其他对象的数据初始化 以前未初始化的对象。

A(const A& rhs) : data_(rhs.data_) {}

例如:

A aa;
A a = aa;  //copy constructor

赋值运算符用于用其他对象的数据替换 先前初始化的对象的数据。

A& operator=(const A& rhs) {data_ = rhs.data_; return *this;}

例如:

A aa;
A a;
a = aa;  // assignment operator

您可以将复制构造替换为默认构造加上赋值,但这样做的效率较低。

(顺便说一句: 我上面的实现正是编译器免费提供的,因此手动实现它们没有多大意义。如果您拥有这两者之一,那么您很可能正在手动管理某些资源。在这种情况下,每个 三的法则,您很可能还需要另一个加上一个析构函数。)

复制建构子和赋值运算符之间的区别会给新程序员带来很多困惑,但这并不是那么困难。总结:

  • 如果在进行复制之前必须创建一个新对象,则使用复制建构子。
  • 如果在进行复制之前不必创建新对象,则使用赋值运算符。

赋值运算符示例:

Base obj1(5); //calls Base class constructor
Base obj2; //calls Base class default constructor
obj2 = obj1; //calls assignment operator

复制建构子的例子:

Base obj1(5);
Base obj2 = obj1; //calls copy constructor

@ Luchian Grigore 说的是这样实现的

class A
{
public :
int a;
A(){ cout<<"default constructor"<<endl;};
A(const A& other){ cout<<"copy constructor"<<endl;};
A& operator = (const A& other){cout <<"assignment operator"<<endl;}
};


void main()
{
A sampleObj; //Calls default constructor
sampleObj.a = 10;


A copyConsObj  = sampleObj; //Initializing calls copy constructor


A assignOpObj; //Calls default constrcutor
assignOpObj = sampleObj; //Object Created before so it calls assignment operator
}

输出


缺省构造函数


复制建构子


缺省构造函数


赋值运算符赋值运算符


复制建构子和赋值构造函数的区别是:

  1. 如果是复制建构子,它会创建一个新对象
  2. 在赋值构造函数的情况下,它不会创建任何对象,这意味着它应用于已经创建的对象(<o1>=<o2>)。

而且两者的基本功能是相同的,它们会逐个成员地将数据从 o2复制到 o1。

关于复制建构子,还有一点需要补充:

  • 当通过值传递对象时,它将使用复制建构子

  • 当一个对象通过值从函数返回时,它将使用复制建构子

  • 当使用另一个对象的值初始化一个对象时(如您给出的示例)。

简而言之,

当从现有对象创建一个新对象作为现有对象的副本时,将调用复制建构子。 当已初始化的对象从另一个现有对象分配新值时,将调用赋值运算符。

例子-

t2 = t1;  // calls assignment operator, same as "t2.operator=(t1);"
Test t3 = t1;  // calls copy constructor, same as "Test t3(t1);"

关于这个话题,我想再补充一点。 赋值运算符的运算符函数只能作为类的成员函数写入我们不能像其他二进制或一进制运算符那样使它成为朋友函数。