重载operator []多态

时间:2014-04-29 20:47:31

标签: c++ class polymorphism overloading virtual

class Base
{
protected:
    string m_Name;
public:
    virtual string Name() { return m_Name; }
    virtual string Type() = 0;
    virtual bool isEqual(Base* rhs) = 0 ;
};

我有一个抽象类Base。我的代码中的不同类继承自此Base类。 我将这些对象存储在一个容器(Base的指针向量)

struct Container
{
    vector<Base*> vec;
    int Count() { return vec.size(); }
    Base* operator[](int i)
    {
        if (i<=0) throw anexception;
        if (i>=vec.size()) throw anexception;
        return vec[i];
    }
};

我重载了operator [],但我只设法返回一个指针。有没有办法让我可以返回对象vec [i](它是从Base继承的类型)?

3 个答案:

答案 0 :(得分:3)

如果您希望返回vec[i]指向的对象:

,则只需返回引用即可
Base& operator[](int i)
{
    if (i<=0) throw anexception;
    if (i>=vec.size()) throw anexception;
    return *vec[i];
}

但是,如果不知道派生类型,则无法返回对象的副本,因为这需要从旧对象构造新的Base - 这是不可能的,因为Base是抽象的。

答案 1 :(得分:0)

您可以编写一个指定所需类型的函数:

struct Container
{
    ...
    template<typename T>
    T* at(int i)
    {
        ...
        return dynamic_cast<T*>(vec[i]);
    }
};

Container c;
Derived1* d = c.at<Derived1>(3);

如果对象确实是指定类型,则返回有效指针,否则返回空指针。


通常,在运行时不知道通过指向基类的指针访问的多态对象的类型。从基类到类型派生类的唯一方法是使用一种switch语句来处理所有可能的派生类:

operator[]

这当然是你想要避免的事情。

答案 2 :(得分:0)

你不应该。

返回类的实例意味着您需要调用复制或移动构造函数。如果您这样做,那么您将调用基类的复制构造函数。由于基类不了解派生类,因此返回的副本将是派生类的sliced版本。

这意味着如果派生类具有基类中不存在的变量,则它们将被省略。更不用说虚函数将是基类的函数。

您可以返回引用,但我不知道它如何比返回指针更好。如果你不小心使用参考文献,你肯定会接触到切片。