2013-11-12 2 views
2

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

Резюме того, что я хотел бы сделать, это создать абстрактный базовый класс для связанных списков, а затем получить поодиночке/двукратно/умножения связаны/круговые листы из него и т.д.

Вот код:

#ifndef __LISTA_H__ 
#define __LISTA_H__ 

class Elem; 
class JulElem; 

class Lista // Abstract list class 
{ 
public: 
    Lista(); 
    ~Lista(); 

    virtual void dohvatiGlavu() = 0; 
    virtual void dodajNaKraj(int vred) = 0; 
    virtual void dodajIza(Elem* elem, int vr) = 0; 
    virtual void obrisiIza(Elem* elem) = 0; 
    virtual bool prazna() = 0; 
    virtual int velicina() = 0; 


protected: 

    class Elem 
    { 
    protected: 
     int vred; 
    }; 

    virtual Elem* noviElem(); 

private: 
    Elem* glava; 
}; 

class Jul : Lista // Singly linked list 
{ 
public: 
    void dohvatiGlavu(); 
    void dodajNaKraj(int vred); 
    void dodajIza(Elem* elem, int vr); 
    void obrisiIza(Elem* elem); 
    bool prazna(); 
    int velicina(); 

private: 
    class JulElem : Elem 
    { 
    }; 

    JulElem* noviElem(); 

}; 

Это ошибка, я получаю:

error C2555: 'Jul::noviElem': overriding virtual function return type differs and is not covariant from 'Lista::noviElem' 

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

Благодаря

+4

Вы не должны изменять возвращаемый тип функции при переопределении (за исключением тех типов _covariant_, но вам это действительно не нужно). Измените 'JulElem * noviElem();' на 'Elem * noviElem();'. – rodrigo

+0

В этом случае части JulElem были бы обрезаны, что означает, что я получу указатель на Elem вместо JulElem? – blashyrk

+0

@blashyrk: Нет, этот вид * нарезки * происходит только тогда, когда вы возвращаете значение, а не указатель. Но вы не сможете получить доступ к каким-либо членам 'JulElem', если у вас есть указатель на« Elem », поэтому вы, вероятно, захотите вернуть« JulElem * »здесь; вам просто нужно исправить частное наследование, чтобы типы были ковариантными. –

ответ

3

Проблема в том, что наследование является частным, так JulElem* не ковариант с Elem*. Использовать публичное наследование:

class JulElem : public Elem 
       ^^^^^^ 
0

Похоже, вам нужно использовать шаблоны.

Вот пример:

template<class T> 
T Add(T n1, T n2) 
{ 
    T result; 
    result = n1 + n2; 

    return result; 
} 
+0

Спасибо за ответ! Имею ли я какой-либо контроль над тем, какие типы классов допустимы для шаблона? – blashyrk

+0

Возможно, вы могли бы объяснить, как шаблоны решат эту проблему и что этот пример имеет отношение к этому вопросу? Я изо всех сил пытаюсь понять, как это отвечает на вопрос. –

1

Возвращаемый тип функции не может быть перекрытыми. вы должны сделать так: в основании, определить функцию:

virtual void noviElem(Elem** result); 

Параметр «результат» служил в качестве выходного параметра Я

+0

Да, это возможно, если типы ковариантны, поскольку они (почти) находятся здесь. –

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