【问题标题】:When does the compiler creates the copy-constructor in C++?编译器何时在 C++ 中创建复制构造函数?
【发布时间】:2012-06-07 12:38:36
【问题描述】:

例如在下面的代码中:

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) 时会发生按位复制?

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

输出如下:

h 构造后:objectCount = 1

f() 中的 x 参数:objectCount = 1

~HowMany(): objectCount = 0

调用 f() 后:objectCount = 0

~HowMany(): objectCount = -1

~HowMany(): objectCount = -2

非常感谢提前

【问题讨论】:

  • 你怎么知道 itd 没有创建? (顺便说一句,您的标题说“可以”,而您的问题说“不可以”。先解决这个问题。)
  • 检查它的输出。我问的是它什么时候自动创建,什么时候不自动创建。
  • 输出在哪里?您希望我们编译并执行您的代码以查看输出吗?然后回答?
  • 您所说的按位复制是默认的复制构造函数。
  • 您希望为 objectCount 打印什么,您看到了什么? objectCount 不会被自动生成的复制构造函数触及!

标签: c++ copy-constructor


【解决方案1】:

在 C++98 和 C++03 中,编译器总是创建一个复制构造函数,它执行字段的成员复制,除非您明确指定您自己编写1。 p>

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

要获得预期的结果,您必须编写如下内容:

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

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

【讨论】:

  • 值得一提的是,在此类中实现复制构造函数类似于HowMany(const HowMany&amp; objectToCopy) { /* do copying to *this here */ }
  • 这在 C++11 中还不是真的吗?除非我自己编写,否则编译器不会生成复制构造函数吗?
  • @JonathanMee:是的,它应该基本相同,除非与移动构造函数进行一些额外的交互(如果提供了自定义移动构造函数 IIRC,则删除默认的复制构造函数)。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2013-04-29
    • 2019-02-26
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多