Copy constructors and Assignment Operators

坚强是说给别人听的谎言 提交于 2019-12-17 16:40:41

问题


I wrote the following program to test when the copy constructor is called and when the assignment operator is called:


#include 

class Test
{
public:
    Test() :
        iItem (0)
    {
        std::cout << "This is the default ctor" << std::endl;
    }

    Test (const Test& t) :
        iItem (t.iItem)

    {
        std::cout << "This is the copy ctor" << std::endl;
    }

    ~Test()
    {
        std::cout << "This is the dtor" << std::endl;
    }

    const Test& operator=(const Test& t)
    {
        iItem = t.iItem;    
        std::cout << "This is the assignment operator" << std::endl;
        return *this;
    }

private:
    int iItem;
};

int main()
{
    {
        Test t1;
        Test t2 = t1;
    }
    {
        Test t1;
        Test t2 (t1);
    }
    {
        Test t1;
        Test t2;
        t2 = t1;
    }
}

This results in the following output (just added empy lines to make it more understandable):

doronw@DW01:~$ ./test
This is the default ctor
This is the copy ctor
This is the dtor
This is the dtor

This is the default ctor
This is the copy ctor
This is the dtor
This is the dtor

This is the default ctor
This is the default ctor
This is the assignment operator
This is the dtor
This is the dtor


The second and third set behave as expected, but in the first set the copy constructor is called even though the assignment operator is used.

Is this behaviour part of the C++ standard or just a clever compiler optimization (I am using gcc 4.4.1)


回答1:


No assignment operator is used in the first test-case. It just uses the initialization form called "copy initialization". Copy initialization does not consider explicit constructors when initializing the object.

struct A {
  A();

  // explicit copy constructor
  explicit A(A const&);

  // explicit constructor
  explicit A(int);

  // non-explicit "converting" constructor
  A(char const*c);
};

A a;
A b = a; // fail
A b1(a); // succeeds, "direct initialization"

A c = 1; // fail, no converting constructor found
A d(1); // succeeds

A e = "hello"; // succeeds, converting constructor used

Copy initialization is used in those cases that correspond to implicit conversions, where one does not explicitly kick off a conversion, as in function argument passing, and returning from a function.




回答2:


C++ standard 8.5/12

The initialization that occurs in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and brace-enclosed initializer lists (8.5.1) is called copy-initialization and is equivalent to the form

T x = a;

The initialization that occurs in new expressions (5.3.4), static_cast expressions (5.2.9), functional notation type conversions (5.2.3), and base and member initializers (12.6.2) is called direct-initialization and is equivalent to the form

T x(a);



回答3:


Your first set is according to the C++ standard, and not due to some optimization.

Section 12.8 ([class.copy]) of the C++ standard gives a similar example:

class X {
    // ...
public:
    X(int);
    X(const X&, int = 1);
};

X a(1);     // calls X(int);
X b(a, 0);  // calls X(const X&, int);
X c = b;    // calls X(const X&, int);

The last line would be the one matching your case.



来源:https://stackoverflow.com/questions/2027873/copy-constructors-and-assignment-operators

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!