Возможна ли эта структура наследования c ++? - PullRequest
1 голос
/ 25 августа 2011

Я долгое время не программировал на c ++ и хочу простое поведение, которое пока не генерируется ни одним количеством виртуальных ключевых слов:

class Base {
  public:
    int both() { return a(); }
};

class Derived : public Base {
  protected:
    int a();
};

class Problem : public Derived {
};

Problem* p = new Problem();
p.both();

, что дает мне ошибку во время компиляции.Возможно ли такое поведение с C ++?Мне просто нужно предварительное заявление?Виртуальные ключевые слова на все?

Ответы [ 6 ]

4 голосов
/ 25 августа 2011

Вы должны объявить функцию a() как чисто виртуальный метод в классе Base.

class Base {
    int both() {
        return a();
    }

    virtual int a()=0;
};

Затем реализовать метод a() в классе Derived

class Derived : public Base {
    int a(){/*some code here*/}
};

И, наконец, класс Problem не видит метод both(), поскольку он закрыт в Base.Сделай это public.

class Base {
public:
    int both() {
        return a();
    }
};
4 голосов
/ 25 августа 2011

Нет. Вам придется использовать чистый виртуальный a в base.

class Base {
    virtual int a() = 0;
    int both() {
        return a();
    }
};
3 голосов
/ 25 августа 2011

Ваша функция both() по умолчанию закрыта.Попробуйте:

class Base {
public:
    int both() {
        // ...

(В будущем было бы полезно, если бы вы сообщили нам, каково было настоящее сообщение об ошибке.)

2 голосов
/ 25 августа 2011

Вам нужно объявить a() в class Base, иначе компилятор не знает, что с ним делать.

Кроме того, both() в настоящее время является закрытым методом (по умолчанию это классы), и его следует сделать общедоступным, чтобы вызывать его из main.

1 голос
/ 25 августа 2011

Как отмечают другие, вам нужно объявить a() как чисто виртуальный метод Base и изменить доступ к общедоступным, чтобы ваш фрагмент кода работал.

Здесь возможен другой подход в c ++: вместо виртуальных функций вы можете использовать статический полиморфизм через Любопытно повторяющийся шаблон :

template <class D>
class Base : public D
{
public: 
    int both() { return D::a(); }
};

class Derived : public Base<Derived> 
{
public:
    int a();
};

Я публикую этот подход, так как вы спрашиваете, что возможно в c ++. На практике виртуальные методы чаще всего являются лучшим выбором из-за их гибкости.

1 голос
/ 25 августа 2011

У вас есть несколько проблем в вашем коде:

  • , если вы не объявите их общедоступными или защищенными, элементы класса по умолчанию являются закрытыми.
  • вам нужно виртуальное ключевое слово дляопределить виртуальную функцию, которая будет вызываться в родительском объекте.
  • new возвращает указатель на задачу.

Вот полный рабочий код, основанный на вашем тесте:

class Base { 
protected:
virtual int a()=0;
public:
    int both() { 
        return a(); 
    } 
}; 

class Derived : public Base { 
private :
int a()
{
printf("passing through a!");
return 0;
}


}; 

class Problem : public Derived { 
}; 

int main(void)
{
  Problem* p = new Problem(); 
  p->both();
}

проверено на CodePad .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...