Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在c+中重载间接运算符+;_C++_Operator Overloading_Indirection - Fatal编程技术网

C++ 在c+中重载间接运算符+;

C++ 在c+中重载间接运算符+;,c++,operator-overloading,indirection,C++,Operator Overloading,Indirection,我的问题很简单。我有一个类模板,其中包含指向动态分配类型的指针。我想重载间接运算符,以便使用->运算符引用类模板实例时,我会被重定向,就好像我直接使用了其中包含的指针一样 template<class T> class MyClass { T *ptr; ... // created dynamic resource for ptr in the constructor }; 我只需键入: intance->someMemberMethod(); 即使你实例

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

template<class T>
class MyClass
 {
  T *ptr;
  ...
  // created dynamic resource for ptr in the constructor
 };
我只需键入:

intance->someMemberMethod();

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

您可以重载
运算符->
运算符*

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;
    }
};
模板
类MyClass
{
T*ptr;
公众:
T*运算符->(){
返回ptr;
}
//const version,返回指向const的指针,而不仅仅是指向
//强化这个对象的逻辑恒量的观念
常量T*运算符->()常量{
返回ptr;
}
T&运算符*(){
返回*ptr;
}
//const version,返回一个const引用,而不仅仅是一个引用
//强化这个对象的逻辑恒量的观念
常量T&运算符*()常量{
返回*ptr;
}
};
注意,由于语言创建者的设计决定,您不能重载
操作符

此外,您可能会认为
运算符*
会重载乘法运算符而不是解引用运算符。但是,情况并非如此,因为乘法运算符只接受一个参数(而解引用运算符不接受任何参数),因此编译器可以判断哪个是哪个


最后,请注意
operator->
返回指针,但
operator*
返回引用。很容易意外地混淆它们。

使
->
操作员过载:

template <typename T> class MyClass
{
    T * p;
public:
    T       * operator->()       { return p; }  // #1
    T const * operator->() const { return p; }
};
模板类MyClass
{
T*p;
公众:
T*运算符->(){return p;}/#1
T常量*运算符->()常量{return p;}
};

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

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

T * operator->() {return ptr;}
T const * operator->() const {return ptr;}
您可能还需要“尊重”操作符,使其感觉更像一个指针;这将返回一个引用:

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

如果你想深入研究,现代C++设计(Andrei Alexandrescu)对这个主题有一些很好的信息。“我们决定让1非const”——至少,如果我们想的话,我们可以。标准智能指针没有,基本上是因为可以通过
t*const
修改
t
类型的对象。这取决于
实例
是否“在逻辑上”是对另一个对象的间接引用(在这种情况下,模拟标准智能指针)或不间接引用(在这种情况下,诅咒Bjarne,你不能重载
操作符。
)。@SteveJessop:“我们”如“你和我,在进入C++的旅程中”,而不是“我们是所有观点的现存统治者”“我想。对不起,旧习惯:-)回答得好。但是你能区分常量版本和非常量版本的区别吗?我什么时候可以使用它们中的任何一个?以及为什么需要重载
->
*
。为什么仅仅重载
->
是不够的?@SimpleGuy类的用户通常期望
foo->bar
等同于
(*foo).bar
。让他们与众不同会让很多人震惊。@Bernard Oh。。从这个角度来看,这样做很好。。
T * operator->() {return ptr;}
T const * operator->() const {return ptr;}
T & operator*() {return *ptr;}
T const & operator*() const {return *ptr;}