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继承的类型)?
答案 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
版本。
这意味着如果派生类具有基类中不存在的变量,则它们将被省略。更不用说虚函数将是基类的函数。
您可以返回引用,但我不知道它如何比返回指针更好。如果你不小心使用参考文献,你肯定会接触到切片。