【发布时间】:2014-01-28 12:31:35
【问题描述】:
我正在尝试制作一种“收藏”。这个类需要接受所有继承自基类的类。
例如:
假设我们有一个名为“A”的基类,并且我们有很多其他类继承自这个类“A”。所以我们有,类“B”继承自“A”,类“C”继承自“A”,等等,我们有一个名为“collection”的类,它也继承自“A”。类“collection”有一个“std::map”,使用“add”方法保存所有类,并且可以使用“get”检索。
发生的事情是它以某种方式工作,但应用程序转换为“基类”而不是返回传递的类。
我们上代码(看代码上的cmets理解输出):
这是工作代码:
#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”对象,所以错误:
“A 类”没有名为“add”的成员
如果我这样做会变得更糟:
col->get("col2")->saySomething(); // output: Hello from A object
这个想法是,一个集合只接受从基类继承的类,也接受从同一基类继承的其他集合,比如递归。
【问题讨论】:
-
你很惊讶吗?您的
get调用返回A*,A*有add()方法吗?此外,您的Collection类继承 来自A,但不覆盖 方法saySomething(),那么为什么您对输出感到惊讶? -
不要使用公共继承,除非继承的类“是”父类。
Collection不是A,因此从A公开继承它是糟糕的设计。 -
如果要访问不属于
As 接口的方法,则需要强制转换为Collection。 -
@Nim - 你说的没有意义,因为我知道 A 没有实现方法“get”,但重要的是从 A 继承的“集合”具有该方法.
-
@tillaert - 请给我解释一下好吗?
标签: c++ inheritance