赋值运算符和复制构造函数之间有什么区别?

时间:2012-07-29 01:56:57

标签: c++ memory

我不明白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?

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

8 个答案:

答案 0 :(得分:128)

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

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

您可以使用默认构造和赋值替换复制构造,但效率会降低。

(作为旁注:我上面的实现正是编译器免费提供给你的那些,所以手动实现它们没有多大意义。如果你有这两个中的一个,你很可能是手动管理在某种情况下,根据 The Rule of Three ,您很可能还需要另一个加上析构函数。)

答案 1 :(得分:33)

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

  • 如果在复制发生之前必须创建新对象,则使用复制构造函数。
  • 如果在复制发生之前不必创建新对象,则使用赋值运算符。

赋值运算符的示例:

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

答案 2 :(得分:18)

第一个是复制初始化,第二个是赋值。没有赋值构造函数。

A aa=bb;

使用编译器生成的复制构造函数。

A cc;
cc=aa;

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

  

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

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

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;}
};

我还建议你看一下:

Why is copy constructor called instead of conversion constructor?

What is The Rule of Three?

答案 3 :(得分:3)

复制构造函数和赋值构造函数之间的区别是:

  1. 如果是复制构造函数,它会创建一个新对象。(<classname> <o1>=<o2>
  2. 如果是赋值构造函数,它将不会创建任何对象意味着它应用于已创建的对象(<o1>=<o2>)。
  3. 两者的基本功能相同,他们会将数据从o2复制到o1成员。

答案 4 :(得分:2)

@Luchian Grigore Said是如何实施的

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
}

输出


默认构造函数


复制构造函数


默认构造函数


赋值运算符


答案 5 :(得分:2)

简单来说,

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

实施例 -

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

答案 6 :(得分:2)

我想在这个主题上再补充一点。 &#34;赋值运算符的运算符函数应该只作为类的成员函数编写。&#34;与其他二元或一元运算符不同,我们无法将其作为友元函数。

答案 7 :(得分:1)

要添加有关复制构造函数的内容:

  • 按值传递对象时,它将使用复制构造函数

  • 当按值从函数返回对象时,它将使用复制构造函数

  • 使用其他对象的值初始化对象时(如您给出的示例)。