2014-12-29 6 views
1

Я делаю программу, которая решает ряд подобных проблем.Использование объекта «суперкласс» для обработки унаследованных классов

Я начинаю с классом, который выглядит как (например):

class problem { 
    void init(); 
    void solve(); 
    int print_result(); 
} 

, но тогда я хотел бы расширить этот класс для различных задач:

class problem_A : problem { 
    void init(); 
    void solve(); 
    void print_result(); 
} 

class problem_B : problem { 
    void init(); 
    void solve(); 
    void print_result(); 
} 

... 

Но в главном интерфейсе Я хотел бы иметь один объект для любой из проблем (A, B, ...) и обрабатывать их как:

obj.init(); 
obj.solve(); 
obj.print_result(); 

Как это достичь? Какой тип должен быть?

+0

Изучите шаблон шаблона метода шаблона (http://sourcemaking.com/design_patterns/template_method). Также обратите внимание, что без виртуальных функций или использования статического полиморфизма вы не можете переопределить поведение базовых классов. –

+1

звучит как шаблон фабрики. –

+1

@GaneshKamath Это просто более развязанный вариант. –

ответ

1

Вы придерживаться оригинального класса, но сделать методы чистые virtual

class problem { 
    virtual void init() = 0; 
    virtual void solve() = 0; 
    virtual int print_result() = 0; 
} 

Тогда вы можете override эти функции в производных классах

class problem_A : problem { 
    virtual void init() override; 
    virtual void solve() override; 
    virtual void print_result() override; 
} 

Затем вы можете сделать свой объект следующим образом:

problem* obj = new problem_A; 
obj->init(); 
obj->solve(); 
obj->print_result(); 

Это вызовет problem_A, но вы можете использовать указатель на базовый класс problem. Очевидно, убедитесь, что вы очистить память

delete obj; 

Или использовать умные указатели

std::unique_ptr<problem> = std::unique_ptr<problem>(new problem_A); 
+0

Не совсем, либо сделать функции базового класса чисто виртуальными, либо использовать шаблон шаблона. –

+0

Вам также нужно наследовать с помощью 'public' и сделать методы' public' – Sean

+0

@Sean Или сделать все 'struct'. Cyber, вам нужен виртуальный деструктор в базовом классе. – juanchopanza

2

Если вы всегда хотите позвонить init() то solve() затем print_result(), то лучше обернуть это в (для C++) неумело имени шаблона Метод Шаблон:

class problem { 
public: 
    virtual ~problem() = default; 

    void run() { 
     init(); 
     solve(); 
     print_result(); 
    } 

protected: 
    virtual void init() = 0; 
    virtual void solve() = 0; 
    virtual void print_result() = 0; 
}; 

И тогда каждый из ваших явных проблем просто должны обеспечить реализацию Ф.О. r эти функции:

class problem_A : public problem { 
protected: 
    void init() override { .. } 
    void solve() override { .. } 
    void print_result() override { .. } 
}; 

problem* p = new problem_A(..); 
p->run(); // inits, solves, and prints the results for problem A 
Смежные вопросы