c ++:强制转换运算符与分配运算符与转换构造函数优先级

Posted

技术标签:

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

让我们有这个代码:

Test1 t1;
Test2 t2;
t1 = t2;

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

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

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

    分配运算符 转换构造函数和类型转换运算符(不明确) 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&) 不是“复制构造函数”,而是“转换构造函数”。 这篇文章解释了为什么转换运算符具有更高的优先级:***.com/questions/1384007/… 【参考方案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;

调用的输出构造函数

【讨论】:

以上是关于c ++:强制转换运算符与分配运算符与转换构造函数优先级的主要内容,如果未能解决你的问题,请参考以下文章

C强制类型转换与隐式转换

malloc与new相关

C++转换构造函数:将其它类型转换为当前类的类型

C语言各类数据类型间的混合运算

Java Class.cast()与强制转换运算符

c语言字符与ASCII码的转换