2012-02-04 157 views
0

我有一些类的问题。C++类的继承

在代码:

class A 
{ 
public: 
    int num; 
    sayNum() { cout<<num;} 
}; 

class B : public A 
{ 
public: 
    sayNum() { cout<<"my num is: "<<num;} 
}; 

/*somewhere else...*/ 
A foo[10]; 

B something; 
something.num=10; 

foo[0]=something; 

foo[0].sayNum(); 
/*...*/ 

当我调用foo [0] .sayNum();它打印“10”,我希望它打印“我的号码是:10”。我无法改变数组的类型。请注意,这只是一个示例代码,如果我贴我的这将是很难理解:d)

回答

4

此线条:

foo[0]=something; 

副本东西进入数组。因为something(即,类别B)的类型与foo[0](即类别A)的类型不同,所以存在转换。在这种情况下,something切片,只有A部分将生存。

最终的结果是,foo[0]仍然包含class A类型的对象,因此,“我num是”将永远输出。

sayNum()更改为虚拟的,这对于解决您的代码将显示的其他问题的好建议在此情况下无效。

如何解决它,取决于你想达到什么。可能的解决方案是:

  • 改变数组包含指针A* foo[10];注:这意味着你将不得不使用“新”和“删除”。
  • 使用一个std :: vector而不是一个数组:std::vector<A*> foo;额外的好处:一个向量可以随需求增长和缩小。
  • 使用智能指针std::vector<std::shared_ptr<A> > foo;额外好处:不用担心delete了。

但是不知道你想达到什么目的,就不可能建议正确的方法。

1

声明函数sayNum是在一个定义虚拟:

virtual void sayNum() { cout<<num;} 

编辑:感谢对Sjoerd的评论 - 这仍然不会帮助你。如果你想利用多态性的需要创建指向类A的一个数组而不是A级

+5

Althoug这是一个很好的建议,在这种情况下它不够好。对阵列的分配将切片对象,并且只有A部分被复制到阵列中。 – Sjoerd 2012-02-04 14:57:49

+0

@Sjoerd所以我怎么能存储一个不同类的数组? – 2012-02-04 14:59:53

+0

@kittyPL通过将指针(或智能指针)存储到要存储的类型的公共基类中。 – Sjoerd 2012-02-04 15:10:54

1

无阵列,通过分配somethingfoo[0]将其转换为一个A.

这与将float分配给int类似 - 您将丢失所有小数。

1
  1. 您在各个班级中都缺少函数的返回类型。请说出您想返回类型为void

    void sayNum() { cout<<num;}

  2. 当访问数组元素中,使用下标上阵列对象

    例如:

    foo[0]=something;

+0

这不是他遇到的问题。 – 2012-02-04 15:04:57

+1

@izomorphius:OP的代码甚至没有编译**。 – cpx 2012-02-04 15:07:36

+0

我同意。我添加了评论,表明即使你指出的问题是固定的,他的问题仍然存在。 – 2012-02-04 15:25:30

4

1.你应该避免切片
您应该使用A*而不是A。这可以帮助你理解为什么:What is object slicing?

2.您应声明一个类AsayNum()功能A类的virtual
定义应该是这样的:

class A 
{ 
public: 
    int num; 
    virtual void sayNum() { cout << num; } 
}; 

然后你的代码,你说somewhere else可能看起来像这样:

A* foo[10]; 

B something; 
something.num=10; 

foo[0] = &something; 

foo[0]->sayNum();