【问题标题】:C++: unusual operator overloadingC++:异常运算符重载
【发布时间】:2014-02-21 07:27:03
【问题描述】:

这里重载了什么运算符?

operator T * ()

我知道操作符方法的结构如下:

type operator operator-symbol ( parameter-list )

假设我们有以下代码

template<typename T> class SmartPtr
{
public:
    SmartPtr(T* data): member(data) {}
    T* member;      
    T& operator * () { return *member; }  //usage: *TObj    
    T*& operator () () { return member; }  //usage: TObj()
    operator T * () { return member; }   //usage: ???
};

如果您在ideone 上尝试,则不会出现编译错误。那么这里发生了什么?

添加:static_cast&lt;T*&gt;(TObj) 拨打operator T * 对吗?我试过了here

【问题讨论】:

  • 这是一个转换运算符。

标签: c++ operator-overloading operator-keyword static-cast


【解决方案1】:

这是一个转换运算符,它允许将类转换为T*。用法:

T * p = TObj;

智能指针提供这个可能是个坏主意,因为它很容易意外获得非智能指针。标准智能指针通过get() 函数提供显式转换,以防止意外转换。

【讨论】:

  • +1 它是如何工作的? IE。在引擎盖下,会是static_cast&lt;T*&gt;(member)吗?只是好奇
  • @legends2k:不,没有演员表。它只是在需要转换时调用此运算符;所以我的用法示例相当于T * p = TObj.operator T *();,相当于T * p = TObj.member;
  • 我询问了函数内部发生的情况,即说我将 Circle* 包裹在 SmartPtr 中尝试 int *p = TObj 不应该工作,对吧?为什么?成为T* 的成员究竟会发生什么?
  • 我有点奇怪,但是static_cast&lt;T*&gt;(member) call 调用了这个操作符。看看我更新的ideone代码:ideone.com/3yX9na
  • @legends2k:member 没有任何反应;它已经是T*,所以操作员可以简单地返回它(就像它在 OP 的代码中所做的那样)。通常的转换规则会阻止您使用它来初始化不兼容的指针类型。
【解决方案2】:

SmartPtr 对象出现在表达式中时,将调用此运算符,但编译器没有可用的函数来解决其用法:如果在出现 SmartPtr 的地方使用 T* 是合法的,则 @ 987654324@函数被调用生成一个。这意味着my_smartptr-&gt;my_T_member 可以工作,f(T*); f(my_smart_ptr_to_T); 也可以。类似地,iostreams 在 C++11 中有一个 operator bool()(在 C++03 中是 operator void*(),原因是太乏味了)。这有点与来自单个参数的隐式构造函数相反,如果编译器找不到使用该参数的有效匹配项,它可能会尝试使用该参数构造一个对象来代替使用。

【讨论】:

    【解决方案3】:
    operator T * () { return member; }
    

    它是一个所谓的转换运算符。它将 SmartPtr 类型的对象转换为 T * 类型。此外,它是一个隐式转换操作符。因此,当编译器等待 T * 类型的对象时,您可以使用 SmartPtr 类型的对象。 如果要添加关键字显式,则可以使此转换运算符显式。例如

    explicit operator T * () { return member; }
    

    【讨论】:

      猜你喜欢
      • 2020-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 2016-02-19
      • 1970-01-01
      相关资源
      最近更新 更多