2016-03-30 6 views
0

Мой вопрос, если у меня есть что-то вродеC++ - Условные виртуальные функции

class Base { 
... 
public: 
    virtual void func(); 
} 

void Base::func() { 
//Implementation # 1 
} 

class Derived1 : public Base { 
... 
public: 
    void func(); 
} 

void Derived1::func() { 
//Implementation # 1 
} 

class Derived2 : public Base { 
... 
public: 
    void func(); 
} 

void Derived2::func() 
//Implementation # 1 
} 

class Derived3 : public Base { 
... 
public: 
    void func(); 
} 

void Derived3::func() { 
//Implementation # 2 
} 

То, что я пытаюсь сделать, это я хочу Derived1 и Derived2 использовать реализацию FUNC(), который был использован в Базе , но я хочу, чтобы Derived3 использовал func() несколько иначе. Проблема в том, что если я делаю func() виртуальным в Base, то и Derived1, и Derived2 нужно будет реализовать его по-другому, чего я не хочу. Однако, если я не сделаю его виртуальным, то все производные классы будут иметь такую ​​же имплантацию для func(). Как я могу преодолеть эту проблему?

+0

Я не знал, что я мог сделать это. Поэтому было бы правильно сказать, что с общим наследованием Derived1,2,3 будет иметь доступ к func(), реализованному в Base, если они не объявят его в своих собственных классах, и в этом случае используется новое объявление. –

+0

Это верно, за исключением того, что у них все равно будет доступ даже с частным наследованием (хотя метод не будет виден вне производных классов), и даже если переопределить в производном классе, базовый метод все равно может быть явно вызван при желании , – Cameron

+0

Может ли это быть чем-то вроде следующего кода, где вы определяете виртуальную функцию только в Derived1? –

ответ

1

Редактировать

Это будет работать, но если вам не нужно больше работы в этой функции, @ ответ Кэмерона является правильным.

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

class Base 
{ 
public: 
    virtual void foo() { /* Do something */ }; 
}; 

class Derived1 : public Base 
{ 
public: 
    virtual void foo() { /* Do something else */ }; 
}; 

class Derived2 : public Base 
{ 
public: 
    virtual void foo() { Base::foo(); /* Do something */ }; 
}; 
+1

Какой смысл? – SergeyA

+0

@SergeyA, Возможно, ему нужно будет сделать больше вещей в функции, хотя он не указал это в вопросе. – user1708860

6

виртуальная функция не имеют быть переопределены. Derived1 и Derived2 можно просто не обновлять func().

Только чистый виртуальный функция (объявленная с = 0) должна быть переопределена (не абстрактными) производными классами.

+0

Им не нужно делать ** ничего ** об этом (не уверен, что вы подразумеваете под «redeclare»). – SergeyA

+0

@SergeyA: Что непонятно? Кажется, это совершенно разумное описание. –

+0

@KerrekSB, мы обычно используем слово «переопределить». «Redeclaration» - это не то, что указано в стандарте. И если вы в буквальном смысле строите его из стандартных «деклараций» и «re», вы в конечном итоге будете ошибаться, потому что ничто не может быть объявлено снова в той же единице перевода. – SergeyA

0

Просто позвоните внутри FUNC() из Derived1 и Derived2 База Func(), как этот

Base::func(); 

Derived3 FUNC() может иметь различную реализацию.

1

Как вы считали в качестве виртуального func только в производном1?

код, который следует, что работает как (это то, что вы хотели?)

#include <stdio.h> 
#define X 


class Base { 

public: 
    void func(); 
}; 


void Base::func() { 
    printf("Base\n"); 
} 

class Derived1 : public Base { 
public: 
    virtual void func(); 
}; 

void Derived1::func() { 
    printf("derived1\n"); 
}; 

class Derived2 : public Base { 
public: 
}; 

class Derived3 : public Base { 
public: 
}; 

int main(int argc, char **argv) 
{ 
    Base b; 
    Derived1 d1; 
    Derived2 d2; 
    Derived3 d3; 

    b.func(); 
    d1.func(); 
    d2.func(); 
    d3.func(); 

    printf("hello world\n"); 
    return 0; 
} 
+0

Да, да. благодаря –

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