2013-06-29 79 views
0

我有以下代码:C++默认的拷贝构造函数

#include <iostream> 
    #include <string> 
    using namespace std; 
    class Uno { 
    public: Uno() { cout << "X"; } 
    }; 



    int main() 
    { 
      Uno u; 
      Uno k=u; 

      return 0; 
    } 

所以从我个人理解,代码Uno k=u;将创建的u副本。它看起来像构造函数被调用两次。我期待“XX”,但程序只输出“X”。你能解释一下发生了什么事吗?

谢谢

+0

这个不清楚。你的构造函数被调用一次还是两次? –

回答

1

k正在使用默认的拷贝构造函数它不输出的X创建。

尝试添加此:

Uno(const Uno&) { cout << "Y"; } 

,你应该看到XY输出代替。

1

在这种情况下,我相信构造函数没有被调用,因为你没有创建一个新的对象;相反,您正在将旧对象复制到其他位置。

但是,由于您不使用指针,它们应该是独立的;更改为一个不会影响另一个。

该代码不会再次运行构造函数,因为它不构建新的东西。想象一下,创建后你已经对u域进行了一些改变。再次调用构造函数不会生成u的副本,因此C++不会这样做。这有点像复制照片 - 这样做不会让你的相机出现两次失败,因为这可能会产生不同的图像;相反,你通过复印机运行它,这是不同的。

编辑:正如我已被通知,它确实运行a构造函数,只是不是你写的。假设我比喻中的相机有一个内置的复印机,当然这不会引起闪光。

+1

OP *是*通过copy-construction –

+0

创建一个新对象谢谢,这个比喻很有道理。 – focusHard

3

发生了什么事是这样的:

Uno k = u; 

为A(禁止复制)初始化,其拷贝构造Uno对象kUno对象u。复制构造意味着复制构造函数(在本例中由编译器隐式生成)被调用,而不是默认的构造函数。

这就是为什么您输出的消息在k初始化过程中没有得到打印:您的构造函数没有被调用;相反,另一个(隐式生成)构造函数被调用。

还要注意的是,上面的声明等效于这个一般

Uno k; 
k = u; 

在该最后片段中,表达k = u分配,而不是一个初始化。尽管这两个构造都使用了=符号,但不应该让你迷惑。

1

这是因为你的类没有复制构造函数。如果没有创建拷贝构造函数,那么C++将调用默认的构造函数。这显然不具有“X”行的cout < <。

Uno u;  // your constructor called, --> X to output 
Uno k = u; // default copy constructor called 

但是拷贝构造函数是没有意义的,如果你没有成员变量。

所以我们可以说这是你想要什么:

#include <iostream> 
#include <string> 

using namespace std; 

class Uno 
{ 
    public: 

    string text; 

    // constructor 
    Uno() 
    { 
     text = "X"; 
     cout << text; 
    } 

    // copy constructor 
    Uno(const Uno &o) 
    { 
     text = o.text; 
     cout << text; 
    } 
}; 

int main() 
{ 
     Uno u;  // call constructor -> X 
     u.text = "Y"; // change text in constructed object 
     Uno k=u;  // create new object via calling copy constructor --> Y 
         // so u.text copied to k.text 

     return 0; 
} 

我建议learncpp.com的文章,他们是非常有用的,让事情变得简单。

关于拷贝构造函数和赋值运算符

更多信息: http://www.learncpp.com/cpp-tutorial/911-the-copy-constructor-and-overloading-the-assignment-operator/

0

我的学究把帽子一会...除非你明确地告诉编译器,否则,你总是有,默认情况下,拷贝构造函数:

Uno(const Uno & other); 

和赋值运算符:

Uno & operator=(const Uno & other); 

你是否要求与否。如果不定义任何其他构造函数,你也可以得到默认的构造函数:

Uno(); 

既然你已经定义了无参数的构造函数,你会被用来代替去年的默认。

当你定义的变量:

Uno u; 

你的构造函数是用来初始化对象实例。当你做任务:使用

Uno k=u; 

赋值运算符。

如何避免复制或分配对象?声明它们是私人的,并且不需要执行它们:

class Uno 
{ 
private: 
    Uno(const Uno &); 
    Uno & operator=(const Uno &); 
     ... 
}; 
+0

你确定在'Uno k = u;'赋值运算符是否被使用? –