C++ class inheritance

C++ class inheritance

本文关键字:inheritance class C++      更新时间:2023-10-16

我对类有点问题。

代码中:

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)

此行:

foo[0]=something;

内容复制到数组中。因为something的类型(即B类)与foo[0]的类型(例如A类)不同,所以存在转换。在这种情况下,something将被切片,并且只有A部分将存活下来。

最终结果是foo[0]仍然包含一个类型为class A的对象,因此"my num is"将永远不会输出。

sayNum()更改为虚拟,这是解决代码将显示的其他问题的好建议,但在这种情况下没有帮助。

如何解决它,取决于你想要实现什么。可能的解决方案有:

  • 将数组更改为包含指针:A* foo[10];注意:这意味着您必须使用"new"answers"delete"
  • 使用std::vector而不是数组:std::vector<A*> foo;其他好处:vector可以根据需要增长和收缩
  • 使用智能指针:std::vector<std::shared_ptr<A> > foo;其他好处:不再担心delete

但是,如果不知道自己想要实现什么,就不可能提出正确的方法。

1。您应该避免切片
您应该使用A*而不是A。这可以帮助您理解为什么:什么是对象切片?

2.应将类AsayNum()函数声明为virtual
A类的定义应该如下所示:

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();

否,通过将something分配给foo[0],可以将其转换为A.

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

  1. 您在每个类中都缺少函数的返回类型。假设您希望返回类型为void:

    void sayNum() { cout<<num;}

  2. 访问数组元素时,使用数组对象:上的下标

    例如:

    foo[0]=something;

在A:的定义中将函数sayNum声明为虚拟

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

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