简体   繁体   English

复制构造函数和赋值运算符

[英]Copy constructors and Assignment Operators

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): 这将导致以下输出(仅添加了empy行以使其更易于理解):

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) 此行为是C ++标准的一部分,还是仅仅是聪明的编译器优化(我正在使用gcc 4.4.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. 在与隐式转换相对应的情况下使用复制初始化,在这种情况下,隐式转换不会像函数参数传递和从函数返回那样显式启动转换。

C++ standard 8.5/12 C ++标准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 在参数传递,函数返回,引发异常(15.1),处理异常(15.3)和括号括起来的初始化列表(8.5.1)中发生的初始化称为复制初始化,并且等效于以下形式

 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 在新表达式(5.3.4),static_cast表达式(5.2.9),功能符号类型转换(5.2.3)以及基和成员初始化程序(12.6.2)中发生的初始化称为直接初始化,并且等效于表格

 T x(a); 

Your first set is according to the C++ standard, and not due to some optimization. 您的第一组内容是根据C ++标准制定的,而不是由于某些优化而造成的。

Section 12.8 ( [class.copy] ) of the C++ standard gives a similar example: C ++标准的第12.8节( [class.copy] )提供了一个类似的示例:

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. 最后一行将是与您的情况匹配的那一行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过示例了解复制构造函数和赋值运算符 - Understanding copy constructors and assignment operators with an example 初始化器列表:复制构造函数和赋值运算符=冗余? - Initializer lists: copy constructors and assignment operators = redundancy? 删除复制构造函数和复制赋值运算符。 哪一项至关重要? - Deleting copy constructors and copy assignment operators. Which of them are essential? 删除默认C ++复制和移动构造函数和赋值运算符的缺点? - Disadvantages to deleting default C++ copy and move constructors and assignment operators? 删除基类中的复制和移动构造函数/赋值运算符就足够了吗? - Is deleting copy and move constructors/assignment operators in base class enough? 在将对象传递给函数的过程中删除了复制/移动构造函数和赋值运算符后,没有得到编译时错误 - Did not get a compile time error after deleting copy/move constructors and assignment operators during passing object to function 是否为派生类生成了移动构造函数/赋值运算符 - Are move constructors/assignment operators generated for derived classes 具有多态性的复制构造函数和赋值运算符 - Copy constructor and assignment operators with polymorphism 为什么C ++ auto_ptr有两个复制构造函数和两个赋值运算符,但是一个默认构造函数? - Why does C++ auto_ptr have two copy constructors and two assignment operators but one default constructor? C ++-组合复制/移动运算符和构造函数 - C++ - Combining Copy/Move operators and constructors
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM