我可以在返回子类类型的基类上创建赋值运算符

时间:2013-04-25 09:01:51

标签: c++ templates operator-overloading

对不好的标题感到抱歉......我有一个基类,如:

template<class T>
class GPtr
{
public:
    typedef T BaseType;

    GPtr& operator=(const BaseType& rhs)
    {
        ...
    }
};

我经常想要创建子类化的专业化,如:

class GraphicPtr : public GPtr<Graphic>
{
...
};

然而,我的基类赋值运算符仍然返回GPtr<Graphic>而不是GraphicPtr,如果核心赋值运算符功能稍后要更改,则必须复制粘贴代码很烦人。

是否有一种简洁的方法来定义基类赋值运算符,以便返回正在使用的实际类的类型?

3 个答案:

答案 0 :(得分:1)

在C ++中,基类不知道它是孩子。您可以添加将作为派生类的模板参数并使用它。

template<class T, class Derived>
class GPtr
{
public:
    typedef T BaseType;

    Derived& operator=(const BaseType& rhs)
    {
        ...
    }
};

答案 1 :(得分:1)

也许您可以使用CRTP代替?

#include <iostream>

template<class Derived>
class GPtr
{
public:
    typedef Derived DerivedType;

    GPtr& operator=(const GPtr& rhs)
    {
        std::cout << "GPtr::operator=" << std::endl;

        return *this;
    }
};

class GraphicDerived : public GPtr<GraphicDerived>
{
    public: 

        GraphicDerived& operator=(const GraphicDerived& rhs)
        {
            std::cout << "GraphicDerived::operator=" << std::endl;
            // Inheiriting shadows the name of the base operator= which 
            // needs to be explicitly called.
            GPtr<GraphicDerived>::operator=(rhs); 
            return *this;
        };
};

class Graphic {};

using namespace std;

int main()
{


    GraphicDerived one; 
    GraphicDerived two;

    cout << "derived assignment: " << endl;
    one = two;

    GPtr<Graphic> ptrOne;
    GPtr<Graphic> ptrTwo;

    cout << "GPtr assignment stnadalone : " << endl;

    ptrOne = ptrTwo; 
};

结果:

derived assignment: 
GraphicDerived::operator=
GPtr::operator=
GPtr assignment stnadalone : 
GPtr::operator=

答案 2 :(得分:1)

你所要求的并没有多大意义。当分配基础对象时,它不可能知道从中调用哪个潜在无限数量的派生类型,因此在每种情况下都不能返回不同的类型。此外,即使可能,也不可能在实际代码中使用它。

C ++在运行时解析除了多态调用之外的所有内容,即使对于多态调用,它也只会延迟查找精确覆盖,而不是签名(即使使用协变返回类型,也会使用基本覆盖的返回类型。

从技术上讲,可以使用或不使用模板来完成,但所有这些都表现出相同的核心问题:基类只能是单个类型的基类,由类型返回的类型赋值运算符,将可用性限制为 base 类。

您想要解决的真正问题是什么?

您采取的方法似乎不合适。如果你解释了你想要实现的目标,以便人们可以提出其他方法,那就更好了。