簡體   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