2016-10-13 2 views
0

Я пишу две программы, скажем, калькулятор и шахматную игру. Они разделяют много кода (управление интерфейсом, открытие/сохранение файлов), и я пытаюсь найти оптимальную практику, чтобы избежать повторения кода.Избегание повторного кода с производными классами C++

Моя идея состояла в том, чтобы создать родительский класс, назовем его Generic_Program, который имеет все общие функции и выводит дочерние классы.

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

class Generic_Program { 
    void SaveConfig() { 
     // Write general parameters to a file 
    } 
    void Exit() { 
     SaveConfig(); //First save configuration 
     // Configuration saved, do exit routines, like make window invisible, etc. 
    } 
} 

class Calculator : Generic_Program { 
    void SaveConfig() { 
     Generic_Program::SaveConfig(); //Write generic parameters 
     // Write calculator-specific data, like calculation results, etc. 
    } 
} 

class Chess : Generic_Program { 
    void SaveConfig() { 
     Generic_Program::SaveConfig(); //Write generic parameters 
     // Write chess-specific data, like player scores, etc. 
    } 
} 

Теперь, я хотел бы быть в состоянии назвать Exit() из обеих программ. Желаемое поведение заключается в том, что они сохраняют свои общие и конкретные данные, а затем выходят.

Если я сделаю это с помощью вышеуказанного кода, он выберет родительский класс SaveConfig() и, таким образом, сохранит только общие данные программы.

Я мог бы, конечно, написать определенные подпрограммы Exit() для дочерних классов, но дело в том, чтобы писать общий код только один раз.

Есть ли способ вызвать SaveConfig() детей из родительского класса? Или лучше всего избегать повторного кода в этом случае?

+1

подстановок функция шаблона шаблон. –

+4

http://stackoverflow.com/questions/2391679/why-do-we-need-virtual-functions-in-c – drescherjm

+2

@drescherjm. Успешно справился. –

ответ

1

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

Calculator::exit() { 
    GenericProgram::exit(); 
    std::cout << "do Chess configs" << std::endl; 
    // if needed can call parent routine again, GenericProgram::finish_configs(); 
} 

Если вы хотите, чтобы вызвать Выход рутину базового объекта и иметь его называют Выход дочернего объекта. Объявите виртуальную процедуру ExitSub в базовом объекте.

virtual void GenericProgram::ExitSub(); 

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

Generic_Program::ExitSub() { // do nothing }; 

и объявить/определить версию для каждого дочернего объекта, например:

Chess::ExitSub() { 
    std::cout << "do chess configs" << std::cout; 
} 

DECLARE/определить Выход подпрограммы в Generic_Program, который вызывает дочерние объекты ExitSub рутина. (это полиморфизм).

Generic_Program::Exit() { 
    SaveConfig(); // First save configuration 
    ExitSub(); // invoke sub object configuration 
} 

затем, чтобы вызвать процедуру выхода из базового объекта

MyGenericProgram.Exit(); 
+0

Спасибо, Грегг. Именно то, что я искал. Основная идея заключается в том, чтобы избежать повторных подпрограмм Exit() и родительский вызов SaveConfig() их детей. Ваш пример делает именно это. – Szak1

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