我正试图制作一种“收藏品”。该类需要接受从基类继承的所有类。
例如:
想象一下,我们有一个名为“A”的基类,我们还有许多继承自这个类“A”的其他类。所以我们有,继承自“A”的类“B”,继承自“A”的类“C”,依此类推,我们有一个名为“collection”的类,它也继承自“A”。类“collection”有一个“std :: map”,使用“add”方法保存所有类,并可以使用“get”进行检索。
发生的事情是它以某种方式工作,但应用程序转换为“基类”而不是返回传递的类。
让我们转到代码(请参阅有关代码的注释以了解输出):
这是工作代码:
#include <iostream>
#include <string>
#include <map>
class A
{
public:
virtual void saySomething()
{
std::cout << "Hello from A object" << std::endl;
}
};
class B : public A
{
public:
void saySomething()
{
std::cout << "Hello from B object" << std::endl;
}
};
class C : public A
{
void saySomething()
{
std::cout << "Hello from C object" << std::endl;
}
};
class Collection : public A
{
public:
void add(const std::string & key, A * value)
{
storage[key] = value;
}
A * get(const std::string & key)
{
return storage[key];
}
private:
std::map<std::string, A *> storage;
};
int main( int argc, char ** argv )
{
B * b = new B;
C * c = new C;
Collection * col = new Collection;
Collection * col2 = new Collection;
col->add("b", b); // works, because "b" inherits from "A" class.
col->add("c", c); // works, because "c" inherits from "A" class.
col->add("col2", col2); // watch this part...
col->get("b")->saySomething(); // works - Output: Hello from B object
col->get("c")->saySomething(); // works - Output: Hello from C object
return 0;
}
它有效,但当我尝试检索“col2”并使用他的方法时......
col->get("col2")->add("b", b);
// output: error: 'class A' has no member named 'add'
如果我没错,它需要工作,因为“get”方法返回对象,所以我有“col2”对象的方法对吗?如果你回答是,我们有同样的想法,我不知道发生了什么。在“b”和“c”对象上它返回对象并且我有“saySomething”方法,但是当我尝试检索“col2”时,它将对象作为“A”对象,因此错误:< / p>
'A类'没有名为'add'的成员
如果我这样做会变得更糟:
col->get("col2")->saySomething(); // output: Hello from A object
这个想法是,一个集合只接受从基类继承的类,并接受从同一基类继承的其他集合,如递归。
答案 0 :(得分:2)
C ++具有静态类型,因此当您拥有类型为A
的对象时 - 这就是您的get
方法返回的内容 - 只能使用A
中声明的方法。要在add
的结果上调用get
,您需要使用static_cast
或dynamic_cast
进行投射,或者完全重新考虑您的类层次结构。为什么Collection
需要继承A
? (并回答你的上一个问题,因为它继承了,如果你调用saySomething
,它将调用A
中声明的方法,因为Collection
不提供自己的覆盖。)