我的问题很简单。我有一个类模板,它包含一个指向动态分配类型的指针。我想重载间接运算符,以便引用带有 - >的类模板实例。运算符我被重定向,好像我直接使用了包含在内的指针。
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
包含的那样。如何通过重载运算符来弥补这个差距?
答案 0 :(得分:11)
您可以重载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*
返回引用。很容易让他们感到困惑。
答案 1 :(得分:5)
重载->
运算符:
template <typename T> class MyClass
{
T * p;
public:
T * operator->() { return p; } // #1
T const * operator->() const { return p; }
};
请注意,两个重载都不会改变对象;尽管如此,我们决定将#1设为非常量,以便将对象的常量传递给指针。这有时被称为“深度常数传播”或类似的东西。语言D更进一步。
答案 2 :(得分:3)
可以重载成员访问运算符以返回指向要访问的对象的指针:
T * operator->() {return ptr;}
T const * operator->() const {return ptr;}
您可能还需要deference运算符,使其更像是指针;这会返回一个引用:
T & operator*() {return *ptr;}
T const & operator*() const {return *ptr;}