2010-12-13 6 views
-1

Im пытается вывести следующее:Какие функции должны быть виртуальными для вывода определенных элементов?

apple 
banana 
orange 
banana 

Должен ли я сделать мои функции виртуального для вывода?

class Red 
{ 
public: 
    void PrintMe() { Foo(); Bar(); } 
    void Foo() { printf("pear\n"); } 
    void Bar() { printf("lemon\n"); } 
}; 

class Green : public Red 
{ 
public: 
    void PrintMe() { Bar(); Foo(); } 
    void Foo() { printf("apple\n"); } 
    void Bar() { printf("banana\n"); } 
}; 

class Blue : public Green 
{ 
public: 
    void Foo() { printf("orange\n"); } 
    void Bar() { printf("grape\n"); } 
}; 
int main(int argc, char* argv[]) 
{ 
    Green g; 
    Blue b; 

    Red *pR1 = &g; 
    Red *pR2 = &b; 
    pR1->PrintMe(); 
    pR2->PrintMe(); 
} 
+0

Проголосовало за закрытие этого больного вопроса. Слишком много вопросов, на которые можно ответить. –

+1

Нет голосов, чтобы закрыть и не согласиться с -1. У этого вопроса есть два правильных ответа (да и другие вопросы, или нет, потому что). Пища для размышлений. –

+0

$ 20 говорит, что OP никогда не выбирает ответа и никогда не исправляет вопрос, чтобы иметь смысл. –

ответ

0

Да, в противном случае вы печатаете два красных.

0

Red::Foo() и Red::Bar() должны быть виртуальными.

+0

'Green :: PrintMe' вызывает' Foo' и 'Bar' в обратном порядке по сравнению с' Red :: PrintMe'. –

+0

Извините, не заметил, что –

+0

@larsmans Да, но если я не ошибаюсь, он хочет напечатать «яблочный банан», что означает, что ему нужно вызвать «Red :: PrintMe()» и «Green :: PrintMe»() '- красная селедка. –

0

Там, кажется, некоторые проблемы с вашим кодом: вы определяете класс с именем красного, но затем Зеленый наследует от класса с именем Red

Во всяком случае, если красный ваш базовый класс, и вы хотите, чтобы другие классы переопределили свои методы, вам нужно объявить их virtual.

0

Краткий ответ: PrintMe() должен быть виртуальным.

Объяснение:

Так как вы хотите, чтобы вызвать метод специализированного объекта, на который указывает указатель на базовый класс, вы должны сделать этот метод виртуальным.

// Base class pointer pointing to specialized class 
Red *pR1 = new Green(); 

// If PrintMe() is not virtual, this call will be Red::PrintMe(). 
// If you want to call Green::PrintMe, make it virtual. 
pR1->PrintMe(); 
0

LOL! Никто не получил это право!

Вам нужно сделать PrintMe виртуальным, потому что порядок foo/bar может измениться.

Вам необходимо сделать Foo и Bar виртуальными, потому что они делают разные вещи.

Вам необходимо сделать DESTRUCTOR виртуальным, потому что вы реализуете полиморфную высшую сущность. Это даже не в вашем коде. Ваш конкретный тест main() не нужен, но наиболее разумные, нетривиальные применения.

Редактировать: Хорошо, может быть, я тоже ошибся. Если вы не хотите, чтобы PrintMe фактически переопределяла поведение при использовании с базовым указателем, он не должен быть виртуальным. Ваш код немного запутан. Никто не сделал бы этого таким образом.

2

Там нет никакого способа, вы можете получить «яблоко банан оранжевый банан», как выход с вашей текущей настройки, потому что:

  1. Для печати «яблоко банан» с помощью Red *pR1, вы должны сделать Foo и Bar виртуальным.
  2. Как только вы объявляете функцию виртуальной, она остается во всех производных классах.
  3. С Bar является виртуальным, pR2->PrintMe() будет печатать «оранжевый виноград» - нет способа напечатать «банан».
+0

OP может объявить Bar const в синем. Тогда это не будет отменой. –

+1

@Noah Roberts: Я только сказал, что это невозможно «с текущей настройкой», потому что вопрос OP состоял только в том, чтобы сделать «некоторые функции виртуальными». – casablanca

+0

Ну, в текущей настройке тоже нет виртуальных функций, так что вы идете;) –