抽象类类型...不允许,纯虚函数不被覆盖

Posted

技术标签:

【中文标题】抽象类类型...不允许,纯虚函数不被覆盖【英文标题】:abstract class type ... is not allowed, pure virtual function is not override 【发布时间】:2015-10-08 13:57:46 【问题描述】:

我想写几个类的小程序。

一等号:

class Number

public:
    virtual int compare(Number& a) = 0;
    virtual string toString() = 0;
    virtual void fillRandom() = 0;
;

继承自 Number 的第二类 Rational

class Rational:Number

public:
    int l;
    int m;
    Rational(int a, int b)
    
        this->l = a;
        this->m = b;
    
    int compare(Rational a)   // here is the problem
    string toString()
    void fillRandom()
;

我明白为什么会出现这个错误,我有一个纯虚方法int compare(Number& a),因此在所有子类中我必须有相同的方法。

但是,如果我将 compare 参数更改为 Number,如果不在 compare 中的某处将 Number 转换为 Rational,它将无法工作。

有没有什么方法可以在不强制转换的情况下做到这一点?或者最好的方法是什么?

【问题讨论】:

你需要多态性吗? 是的,这就是我需要的 你也不能通过强制转换来做到这一点,因为Number 参数不必是Rational 请注意,您使用的是私有继承,您可能需要class Rational : public Number @AleksanderMonk - 好的,dynamic_cast 可以完成这项工作,但会将编译时错误转换为运行时错误。不是我想要的。 :-) 【参考方案1】:

首先,您需要有一些内容才能进行比较。这是什么?

a) Rational 是否只能与另一个 Rational 进行比较?或

b) 不知何故 Value(Rational())Value(OtherNumber())?在哪里

class OtherNumber : public Number

     // Some code here

如果是a,那么您需要考虑为什么将compare() 放入超类中。

如果是b,那么你需要抽象另一个函数,比如说

virtual long Value() const = 0;

并更改compare(),使其适用于Value()

virtual int compare(const Number& a)

    // something about Value() and a.Value();

顺便说一句,通常比较函数是const 函数。那就是:

virtual int compare ( const Number& a ) const;

另外,请记住将Number 扩展为public,即

class Rational : public Number

否则你将失去多态行为。

【讨论】:

NumberInOrderFormat 是什么意思? 我更新了答案。只有另一个类实现了 Number 我猜如果你用compareValue() 一起工作,你应该让compare 成为非虚拟的,对吧? 是的,你是对的。但是将 compare() 声明为 virtual 使另一个类可以再次覆盖它。除非该类是final类,否则该函数绝对不能被覆盖,否则virtual是没有坏处的。当然,除了性能敏感代码【参考方案2】:

您可以使用以下签名(在基类和派生类中)(将虚拟声明保留在基类中):

int compare(const Number* a)

所以基本上这个想法是使用指针而不是引用。这应该可以工作,您不必执行任何类型的转换来调用 compare 方法。

但是,使用上面的代码,您仍然必须在 compare 方法主体中将 Number 动态转换为 Rational。此外,您必须考虑到可以调用与 Number 的任何子类进行比较,并且您可能对此行为不感兴趣。因此,您必须添加一些检查以确保您正在与不兼容的类进行比较。

【讨论】:

使用指针与使用引用有何不同? 他们不是在谈论转换为调用,而是在函数本身进行转换。您仍然需要在函数中转换为 Rational 我理解在使用引用时,如果您将派生类传递给定义为接收基类的方法,那么传递的值将被转换为基类。 这与指针的行为相同。您仍然必须在函数内部进行强制转换。 是的,为了将 Number 视为 Rational .. 所以是的,在所有情况下都需要演员表。

以上是关于抽象类类型...不允许,纯虚函数不被覆盖的主要内容,如果未能解决你的问题,请参考以下文章

C++学习笔记11--纯虚函数和抽象类

虚函数和纯虚函数的区别

允许派生类从基本抽象类实现单个纯虚函数

纯虚函数,抽象类

多态—— 纯虚函数和抽象类

纯虚函数和抽象类