繁体   English   中英

重载转换运算符的后果

[英]Consequences of overloading the conversion operator

我有一个带有重载转换运算符的类,如下所示:

template <class T> class Pointer {
    T* object;
public:
    Pointer (T* object): object(object) {}
    operator T* () { return object; }
};

我注意到,有些我通常必须手动重载的运算符现在突然工作,就像PointerT*但有些运算符却没有:

MyClass my_object;
Pointer<MyClass> pointer (&my_object);
if (pointer) { /* ... */ } // works
if (pointer == &my_object) { /* ... */ } // works
(*pointer).some_method (); // works
pointer->some_method (); // doesn't work
pointer = pointer + 1; // works
pointer++; // doesn't work

假设这是根据标准的正确行为,那么我怎么知道什么有效,什么无效(没有反复试验),更重要的是,为什么要这样做呢?

上述某些操作之所以有效,是因为编译器可以将自定义类型转换为: Pointer<MyClass>转换为原始指针: MyClass*隐式地使用SINGLE用户定义的转换。 隐式转换有严格的规则,请参见此处

每当在上下文中使用某种T1类型的表达式但不接受该类型但接受某种其他T2类型的表达式时,都会执行隐式转换,尤其是:

 (1) When the expression is used as the argument when calling a function that is declared with T2 as parameter. (2) When the expression is used as an operand with an operator that expects T2 (3) When initializing a new object of type T2, including return statement in a function returning T2. (4) When the expression is used in a switch statement (T2 is integral type) (5) When the expression is used in an if statement or a loop (T2 is bool) 

通过上面的示例进行调查,如果有人可以验证或纠正我的扣除额,我将不胜感激。

  • 情况(5), if声明:

    if (pointer) { /* ... */ } // works

  • 情况(2),带有操作数的operator==可以隐式转换为MyClass*

    if (pointer == &my_object) { /* ... */ } // works

  • 情况(2),间接operator*operator* )可以隐式转换为MyClass* ,然后是结构引用( operator. ):

    (*pointer).some_method (); // works

  • 不匹配任何情况, operator->不接受任何可以隐式转换的参数:

    pointer->some_method (); // doesn't work

  • 情况(2): operator+取可以隐式转换为MyClass*操作数,并使用构造函数和operator=将返回值分配给Pointer<MyClass> 请注意,向构造函数添加explicit可防止编译,因为表达式的返回类型: pointer + 1MyClass* ,因此隐式调用采用MyClass*构造函数:

    pointer = pointer + 1; // works

  • 与任何情况都不匹配; 注意,即使显式转换为MyClass* (例如static_cast<MyClass*>(pointer)++ )也无济于事,因为这里需要左值; 解决方法是: auto ptr = &(*pointer); ptr++; auto ptr = &(*pointer); ptr++;

    pointer++; // doesn't work

请记住,重载转换运算符有时可能会导致危险情况,例如。 MyClass* ptr = pointer; delete ptr; 将删除底层资源,并且编译器甚至不会抱怨。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM