转换运算符过载的后果
Consequences of overloading the conversion operator
我有一个类有一个重载的转换运算符,如下所示:
template <class T> class Pointer {
T* object;
public:
Pointer (T* object): object(object) {}
operator T* () { return object; }
};
我注意到,一些我通常必须手动过载的操作员现在突然工作起来,就好像Pointer
是T*
,但有些操作员不是:
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
假设根据标准这是正确的行为,我怎么知道什么有效,什么无效(没有反复试验),更重要的是,为什么会这样?
上面的一些操作之所以有效,是因为编译器可以使用SINGLE用户定义的转换将自定义类型Pointer<MyClass>
隐式转换为原始指针MyClass*
。这里介绍了隐式转换的严格规则。
每当某个类型的表达式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),具有可隐式转换为
MyClass*
:的操作数的operator==
if (pointer == &my_object) { /* ... */ } // works
-
情况(2),间接(
operator*
)取可隐式转换为MyClass*
的操作数,然后结构引用(operator.
):(*pointer).some_method (); // works
-
与任何情况都不匹配,
operator->
不接受任何参数,这些参数可以隐式转换:pointer->some_method (); // doesn't work
-
情况(2):
operator+
取可隐式转换为MyClass*
的操作数,使用构造函数和operator=
为Pointer<MyClass>
赋值;注意,将explicit
添加到构造函数中会阻止编译,因为表达式的返回类型:pointer + 1
是MyClass*
,所以采用MyClass*
的构造函数被隐式调用:pointer = pointer + 1; // works
-
与任何情况都不匹配;注意,即使显式转换为
MyClass*
(例如static_cast<MyClass*>(pointer)++
)也无济于事,因为这里需要左值;解决方法是:auto ptr = &(*pointer); ptr++;
:pointer++; // doesn't work
请记住,重载转换运算符有时会导致危险的情况,例如MyClass* ptr = pointer; delete ptr;
会删除底层资源,编译器甚至不会抱怨。
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 转换运算符过载的后果
- "screwing up"赋值运算符的后果是什么?