2

例如在下面的代码中:

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

非常感谢提前

4

2 回答 2

9

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

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

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

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

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

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

于 2013-10-09T07:05:33.510 回答