1

抱歉标题不好...我有一个基类,例如:

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

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

我经常想进行子类专业化,例如:

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

但是,我的基类赋值运算符仍然GPtr<Graphic>不返回GraphicPtr,并且必须复制粘贴代码以防核心赋值运算符功能稍后更改,这很烦人。

有没有一种巧妙的方法来定义基类赋值运算符,以便它返回实际使用的类的类型?

4

3 回答 3

1

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

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

    Derived& operator=(const BaseType& rhs)
    {
        ...
    }
};
于 2013-04-25T09:09:01.900 回答
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=
于 2013-04-25T09:27:07.577 回答
1

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

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

从技术上讲,无论有没有模板都可以,它们都表现出相同的核心问题:基类只能是单一类型的基类,即赋值运算符返回的类型,限制了作为类的可用性.

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

您采取的方法似乎不合适。如果您解释您要达到的目标,以便人们可以提出其他方法,那会更好。

于 2013-04-25T11:57:10.323 回答