一个变量声明创建多个实例

时间:2015-03-13 16:50:20

标签: c++

这是一个简单的例子:

class A {
public:
  A() {
    printf("%p C1\n", this);
  } 
  A(const char* p) {
    printf("%p C2\n", this);
  }
};

int main(int argc, char *argv[]) {
  A a;
  a = "abc";
}

在代码中,尽管A仅被声明一次,但有两个A实例被创建。构造函数被调用两次。我可以在VS 2013和gnu C ++中重现这一点。

想知道这种行为是错误还是规范的一部分。

2 个答案:

答案 0 :(得分:6)

这是规范的一部分。当你这样做时:

a = "abc";

使用A构造函数在RHS上的"abc"表达式创建临时A(const char* p)对象。这用于将值分配给a

如果你这样做了

A a = "abc";

你只能看到一个构造函数调用。

答案 1 :(得分:4)

因为您没有禁用自动生成的赋值运算符或复制构造函数,所以您的类实际上对编译器来说是这样的:

class A {
public:
  A() {
    printf("%p C1\n", this);
  }
  A(const A& rhs) { }
  A(const char* p) {
    printf("%p C2\n", this);
  }
  A& operator=(const A& rhs) { return *this; }
};

因此a = "abc"被解释为a.operator=( A("abc") )

它期望const A&作为operator=的参数,它可以构造,因为您提供了构造函数A(const char*)

您可以通过使构造函数显式来阻止意外转换。

class A {
public:
  A() {
    printf("%p C1\n", this);
  }
  explicit A(const char* p) {
    printf("%p C2\n", this);
  }
};

然后这应该无法编译:

int main(int argc, char *argv[]) {
  A a;
  a = "abc";
}

除非您明确构建:a = A("abc");