【问题标题】:c++: cast operator vs. assign operator vs. conversion constructor priorityc ++:强制转换运算符与分配运算符与转换构造函数优先级
【发布时间】:2012-09-02 08:59:56
【问题描述】:

让我们有这个代码:

Test1 t1;
Test2 t2;
t1 = t2;

我相信有三种(或更多?)方法可以实现t1 = t2

  • Test1 中重载赋值运算符
  • Test2 中重载类型转换运算符
  • 创建Test1(const Test2&)转换构造函数

根据我的 GCC 测试,这是使用的优先级:

  1. 分配运算符
  2. 转换构造函数和类型转换运算符(不明确)
  3. const 转换构造函数和 const 类型转换运算符(不明确)

请帮助我理解为什么这个优先级。

我使用此代码进行测试(取消注释某些行以尝试)

struct Test2;
struct Test1 {
  Test1() { }
  Test1(const Test2& t) { puts("const constructor wins"); }
//  Test1(Test2& t) { puts("constructor wins"); }
//  Test1& operator=(Test2& t) { puts("assign wins"); }
};

struct Test2 {
  Test2() { }
//  operator Test1() const { puts("const cast wins"); return Test1(); }
//  operator Test1() { puts("cast wins"); return Test1(); }
};


int main() {
  Test1 t1;
  Test2 t2;
  t1 = t2;
  return 0;
}

【问题讨论】:

  • Test1::Test1(const Test2&) 不是“复制构造函数”,而是“转换构造函数”。
  • 这篇文章解释了为什么转换运算符具有更高的优先级:stackoverflow.com/questions/1384007/…

标签: c++ casting copy-constructor assignment-operator


【解决方案1】:

语句t1 = t2;等价于:

t1.operator=(t2);

现在适用重载决议的常规规则。如果有直接匹配,那就是选择的。如果不是,则考虑将隐式转换与(自动生成的,“隐式定义的”)复制赋值运算符一起使用。

有两种可能的隐式、用户定义的转换。所有用户定义的转换计数相等,如果两者都定义,则重载不明确:

  • 通过Test1::Test1(Test2 const &) 转换构造函数将t2 转换为Test1

  • 通过Test2::operator Test1() const 转换运算符将t2 转换为Test1

【讨论】:

  • 在@Luchian 的第二个ideone 示例中,转换函数获胜,因为它将Test2& 绑定到t2,而不是const Test2&。我认为ideone.com/U38vK 也应该是模棱两可的,但似乎 g++ 更喜欢构造函数。
  • 啊哈。如果您要求-pedantic,g++ 确实称它们为模棱两可。调皮的默认g++。
  • @KerrekSB:如果转换运算符不是常量,它会击败转换构造函数并且没有歧义。 liveworkspace.org/code/7795254ae49b4d6350f0ede57615e4c6
  • @JanTuroň:是的,我知道。如果你也将构造函数设为非 const,你可以恢复歧义。
  • @JanTuroň:完全一样的原因。
【解决方案2】:

当我使用以下代码时,优先级优先于构造函数而不是强制转换运算符

 #include<iostream>
 using namespace std;
 class C1;
 class C2
 {
      int x;
 public:
     operator C2()
     {
       C2 temp;
       cout<<"operator function called"<<endl;
       return temp;
    }
 };
class C1
{
   int x;
public:
   C1():x(10){}
   C1(C2)
  {
    cout<<"constructor called"<<endl;
  }
};
 int main()
{
  C1 obj1;
  C2 obj2;
  obj1=obj2;
}

调用的输出构造函数

【讨论】:

    猜你喜欢
    • 2010-11-25
    • 2014-07-28
    • 1970-01-01
    • 2019-05-15
    • 1970-01-01
    • 2012-05-04
    • 2017-07-04
    • 1970-01-01
    • 2016-02-19
    相关资源
    最近更新 更多