【问题标题】:C++ operator overloading weird type conversionC++ 运算符重载奇怪的类型转换
【发布时间】:2014-02-02 02:14:17
【问题描述】:

我有一个简单的 c++ 类向量,它的参数构造函数如下:

Vector::Vector(int size){
   ...
}

基于此实现,以下行是有效的:

Vector v(1);
Vector v2(94);

我的问题是我正在测试我的代码,我发现这也是有效的:

Vector v = 1;

它以某种方式调用了参数构造函数。我还重载了 operator = 但在这种情况下它从未被调用过。这是 c++ 中的正常行为吗?编译器如何将上述赋值视为Vector v(1)?我在 Xcode 5.0(LLVM 编译器)中这样做

【问题讨论】:

  • 直接初始化和复制初始化。

标签: c++ xcode llvm


【解决方案1】:

不是重载运算符=,而是复制初始化。如果你想阻止这种向量的构造,那么你可以使用explicit构造函数。

explicit Vector(int);

现在

Vector v = 1;

不正确。

【讨论】:

  • 如果类的参数构造函数采用 int,这是正常行为吗?
  • @REALFREE 是的,这是预期行为,请参阅 explicit 关键字了解更多信息
【解决方案2】:

这是由于编译器悄悄支持的“自动类型转换”。这就是它在没有复制构造函数的情况下工作的原因。

Bruce Eckel 在他的《Thinking in C++》一书中说:

默认的构造函数、拷贝构造函数、operator=和析构函数可以由编译器自动合成。

【讨论】:

  • 这是由于隐式调用了已定义的构造函数Vector::Vector(int size){...}
  • 谢谢。我得到了它。在这里,内置数据类型与赋值运算符一起使用。这就是为什么编译器不能重载 operator=.
  • “可以合成默认构造函数、复制构造函数、运算符 = 和析构函数” - Eckel 先生的声明似乎描述了编译器如何自动创建/合成默认构造函数等以复制基础和成员,或调用基/成员析构函数。它与问题无关,它是一个被调用的用户定义的构造函数。
【解决方案3】:

下面,x2 会调用 x2 = x1 中的拷贝构造函数;

ClassX  x1() ;
ClassX  x2 =  x1 ;

下面,x4 会在 x4 = x3 中调用复制赋值;

ClassX  x3() ;
ClassX  x4() ;
x4 = x3 ;

如果 ClassX 有明确的复制构造器,那么

ClassX x5(x1) ;  //this will compiled ok 
ClassX x5 = x1 ; //This will fail while compiled

【讨论】:

  • "ClassX x1();" - 这声明了一个函数x1,它不接受任何参数并返回一个ClassX 类型的对象。 x3/x4 也一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
  • 2011-01-15
  • 2012-01-25
相关资源
最近更新 更多