2012-06-07 85 views
2

例如在下面的代码:编译器何时在C++中创建复制构造函数?

class HowMany { 
    static int objectCount; 
    public: 
     HowMany() { 
      objectCount++; 
     } 
     static void print(const string& msg = "") { 
      if(msg.size() != 0) 
       cout << msg << ": "; 

      cout << "objectCount = " << objectCount << endl; 
     } 
     ~HowMany() { 
      objectCount--; 
      print("~HowMany()"); 
     } 
}; 

int HowMany::objectCount = 0; 

// Pass and return BY VALUE: 
HowMany f(HowMany x) { 
    x.print("x argument inside f()"); 
    return x; 
} 

int main() { 
    HowMany h; 
    HowMany::print("after construction of h"); 
    HowMany h2 = f(h); 
    HowMany::print("after call to f()"); 
} 

为什么编译器不会自动为类的howmany创建拷贝构造函数,逐位拷贝发生时调用至f(h)发生地方?

在什么情况下,编译器创建默认的复制构造函数,以及在什么情况下它不创建?

它给输出为:

施工小时后:objectCount = 1

X内˚F()的参数:objectCount = 1周

〜的howmany():objectCount = 0

呼叫f()后:objectCount = 0

〜HowMany():objectCount = -1

〜的howmany():objectCount = -2

许多许多由于事先

+0

你怎么知道itd不会创建? (顺便说一句,你的头衔说“有”,你的问题说“不”),首先解决。) – Nawaz

+0

检查它的输出。我问,什么时候它自动创建,什么时候不创建。 – Luv

+0

输出在哪里?你希望我们编译并执行你的代码来查看输出结果吗?然后回答它? – Nawaz

回答

9

在C++ 98和C++ 03编译器总是产生一个复制构造,其执行成员逐一除非你明确指出你自己写了。

这就是在你的代码中发生的事情:编译器生成的拷贝构造函数没有做任何特别的事情 - 特别是它不会增加objectCount - 所以最终得到一个负数的对象数(所有拷贝的对象都没有不增加柜台,但他们确实减少了)。

为了得到你所期望的结果,你会写是这样的:

HowMany(const HowMany &) { 
     objectCount++; 
} 

  1. 即使你写的拷贝构造函数的原型,但不要不创建默认的拷贝构造函数实现它,并/或将其标记为私有 - 实际上,这就是您如何创建一个不可复制的类。 C++ 11还支持一种特殊的语法来告诉编译器不要生成任何拷贝构造函数。
+0

值得一提的是,在这个类中实现一个拷贝构造函数看起来像'HowMany(const HowMany&objectToCopy){/ *在这里拷贝到* /}'。 –

+0

这在C++ 11中仍然如此吗?除非我自己编写,否则编译器是否会生成复制构造函数? –

+1

@JonathanMee:是的,它应该基本相同,除了一些额外的与移动构造函数的交互(如果提供自定义移动构造函数,IIRC将移除默认的拷贝构造函数)。 –

0

对于每个对象编译器都应该创建拷贝构造函数,这里也拷贝为所有对象h,x和h2创建的构造函数。但是对于h对象拷贝构造函数是没有必要的。接下来你要调用一个函数f,输入参数为h。这里复制构造函数调用并将h中的内容复制到x对象中。对于下一个对象h2也是同样的东西(这里也复制构造函数调用并将x复制到h2)。因为这个原因,只有objectcount不会递增。谢谢。