2015-10-08 3 views
0

Я хочу написать небольшую программу с несколькими классами.абстрактный тип класса ... не разрешен, чистая виртуальная функция не переопределяется

Первый номер класса:

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

Второй класс 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), таким образом, во всех подклассов I должен иметь тот же метод.

Но, если я изменяю compare аргумент Number, он не будет работать без литья номера в Rational где-то в compare.

Есть ли способ сделать это без литья? Или что это лучший способ сделать это?

+2

Вам нужен полиморфизм? – NathanOliver

+0

Да, это то, что мне нужно –

+0

Вы не можете сделать это с актом, так как параметр 'Number' не должен быть' Rational'. –

ответ

3

Прежде всего, вам нужно иметь некоторый контент, чтобы сравнить. Что это?

a) Можно ли сравнить Rational с другим Rational? или

b) каким-либо образом Value(Rational()) vs Value(OtherNumber())? где

class OtherNumber : public Number 
{ 
    // Some code here 
} 

Если, то вам нужно подумать, почему вы положили compare() в супер класс.

Если б, то вам нужно абстрагировать другую функцию, скажет

virtual long Value() const = 0; 

и изменить compare() поэтому она работает на Value():

virtual int compare(const Number& a) 
{ 
    // something about Value() and a.Value(); 
} 

BTW, как правило, функция сравнения является const функция. То есть:

virtual int compare (const Number& a) const; 

Кроме того, не забудьте продлить Number с public, т.е.

class Rational : public Number 

В противном случае вы потеряете полиморфное поведение.

+0

Что вы подразумеваете под 'NumberInOrderFormat'? – anatolyg

+0

Я обновляю ответ. Просто другой класс реализует Number –

+0

. Я полагаю, что если вы делаете дело с 'compare', работая с' Value() ', вы должны сделать' compare' не виртуальным, так? – anatolyg

0

Вы можете использовать подпись ниже (как в базовых и производных классов) (сохранение виртуальной декларации в базе):

int compare(const Number* a){} 

Поэтому в основном идея заключается в том, чтобы использовать указатели вместо ссылки. Это должно работать, и вам не нужно выполнять какие-либо кастинги, чтобы вызвать метод сравнения.

Однако, с приведенным выше кодом вам все равно придется динамически отличать Номер в Rational в теге метода сравнения. Кроме того, вы должны принять во внимание, что можно вызвать сравнение с любым подклассом Number и, возможно, вас это не интересует. Поэтому вам нужно добавить несколько проверок, чтобы убедиться, что вы сравниваете их с несовместимым классом.

+2

Как использование указателя имеет значение от использования ссылки? –

+0

Они не говорили о кастинге для вызова, кроме как в самой функции. Вам все равно придется отбрасывать в функцию «Rational». – NathanOliver

+0

Я понимаю при использовании ссылки, если вы передаете производный класс методу, который был определен для получения базового класса, поэтому переданное значение будет преобразовано в базовый класс. – redobot

Смежные вопросы