c++中的抽象类、函数继承和覆盖

Abstract Classes, Function Inheritance and Override in C++

本文关键字:继承 覆盖 函数 抽象类 c++      更新时间:2023-10-16

A类是抽象类。我想从不同的子类调用相同的方法。编译器没有错误,但是程序崩溃了。

class A
{
    protected:
        MA* array1[10]; //static array of pointers to some other class
        int st;
    public:
    ...
        virtual string ToString() const
        {
            stringstream ss;
            for(int i=0;i<st;i++)
            {
                ss<<array1[i]->getname()<<",";
            }
            return ss.str();
        }
};

ToString方法在类A和B中都有效,但在类C中不起作用

class B: public A
{
    private:
    ...
    public:
        string ToString() const
        {
            return A::ToString();
        }
};
class C: public A
{
    private:
    ...
    public:
        string ToString() const
        {
            return A::ToString();    
        }
};

This is main:

A* P[5];
P[0]=new B();
P[1]=new C();
P[0]->ToString();
P[1]->ToString();

我很确定它在A和b中都不起作用。

唯一的原因似乎是未定义行为。

    http://en.wikipedia.org/wiki/Undefined_behavior
    1. 我预期的问题是违反了三法则(使一个不可复制的?)。

      • 什么是"三原则"?
    2. 或者,您是否正确初始化array1st ?如果不这样做,将导致数组中的不确定值,从而再次出现未定义行为。

问题是:

首先,你的派生类(B和C)继承了类A的公共成员函数(我知道这是显而易见的代码-但是,我们必须从某个地方开始);然而,派生类通过使用相同的函数标识符重写父类(类A)的成员函数。这里的问题是父类不期望继承的派生类覆盖父类,而它们正在这样做。父类只期望派生类继承;因此,当你调用B类和C类的函数时,会发生一些奇怪的事情。

结果产生了两个问题:首先(1),我们在上面讨论过(参见下面的代码);第二(2),派生类不能访问父类的成员函数定义,除非通过父类的对象调用(通常不是这种情况,这里,如果你的函数正确声明)。

那么,你能做什么呢?在父声明和子声明中使用override关键字。

例如:

Class A
{
    private:
    ....
    public:
    virtual returntype functionIndentifier(parameters) override;
};

这和继承有关;然而,在c++中,如果您的类实际上是抽象,则需要使用纯虚函数(通过将该函数设置为0),而不是在抽象类中定义该函数,省略override关键字,并确保每个子类实现并定义该函数。

Class A
{
    private:
    ....
    public:
    virtual returntype functionIndentifier(parameters) = 0;
};

纯虚函数强制子类继承实现-定义-成员函数以满足子类的需要。在这里,如果没有在子类的类定义中定义纯虚拟类,那么—我相信—您实际上会遇到编译时错误。