7

我的问题很简单。我有一个类模板,其中包含一个指向动态分配类型的指针。我想重载间接运算符,以便使用 -> 运算符引用类模板实例,就像我直接使用包含在其中的指针一样重定向。

template<class T>
class MyClass
 {
  T *ptr;
  ...
  // created dynamic resource for ptr in the constructor
 };

创建某种类型的 myclass:

MyClass<SomeObject> instance;

所以我想要的是不必输入:

instance.ptr->someMemberMethod();

我只需键入:

intance->someMemberMethod();

即使你instance不是一个指针,它的行为就好像它是指针instance包含的一样。如何通过重载运算符来弥补这一差距?

4

3 回答 3

13

你可以重载operator->operator*

template<class T>
class MyClass
{
    T* ptr;

public:
    T* operator->() {
        return ptr;
    }

    // const version, returns a pointer-to-const instead of just a pointer to
    // enforce the idea of the logical constness of this object 
    const T* operator->() const {
        return ptr;
    }

    T& operator*() {
        return *ptr;
    }

    // const version, returns a const reference instead of just a reference
    // to enforce the idea of the logical constness of this object
    const T& operator*() const {
        return *ptr;
    }
};

请注意,由于语言创建者的设计决定,您不能重载.运算符。

此外,您可能认为这operator*会重载乘法运算符而不是取消引用运算符。然而,情况并非如此,因为乘法运算符接受一个参数(而解引用运算符不接受任何参数),因此,编译器可以分辨出哪个是哪个。

最后,注意operator->返回一个指针但operator*返回一个引用。很容易不小心混淆它们。

于 2012-01-12T19:21:14.220 回答
5

重载->运算符:

template <typename T> class MyClass
{
    T * p;
public:
    T       * operator->()       { return p; }  // #1
    T const * operator->() const { return p; }
};

请注意,这两个重载都不会改变对象;尽管如此,我们还是决定将#1 设为非常量,以便将对象的常量性遗赠给指针对象。这有时被称为“深度常量传播”或类似的东西。语言 D 更进一步。

于 2012-01-12T19:21:54.803 回答
3

可以重载成员访问运算符以返回指向要访问的对象的指针:

T * operator->() {return ptr;}
T const * operator->() const {return ptr;}

您可能还需要尊重运算符,让它感觉更像是一个指针;这将返回一个引用:

T & operator*() {return *ptr;}
T const & operator*() const {return *ptr;}
于 2012-01-12T19:22:14.357 回答