2015-08-12 6 views
2

Вот сделка. Представьте себе следующее ниже. После загрузки файлов на уровень алгоритма я хочу быть , способным применять 4 разных алгоритма. Таким образом, класс Алгоритм имеет 4 детей, и я хочу сделать что-то вроде этого:Использовать дочерний метод из родительского класса C++

int main(int argc, char* argv[]) { 
    Data *data = new Data(); 
    Parent *alg = new Parent(data); 

    alg->start(); 

    //and this will call the start methods defined in each child. 
} 

детей, как это:

class Child1: public Parent { 
public: 
    int start(); 
} 

class Child2: public Parent { 
public: 
    int start(); 
} 
//etc... 

И что я в детстве начать() метод заключается в следующем:

int Parent::start() { 
    Child1::start(); 
    Child2::start(); 
    //etc.... 
    return 0; 
} 

Но я получаю 'не могу вызвать функцию-член' Child1 :: start() 'и т. Д. Без объекта.' Можно ли это сделать? Вызов дочернего метода из родительского класса?

+0

Я понятия не имею, какую проблему вы пытаетесь решить. Можете ли вы изменить свой вопрос, чтобы объяснить, что вы делаете, и какие трудности у вас есть? – 5gon12eder

+0

Что это за синтаксис 'Child1,2,3,4'? Может ли ',' быть частью идентификаторов C++? – SJuan76

+0

вместо написания полной вещи, я использую ярлыки ... Нет, это не часть C++ – Jack

ответ

2

Взгляните на «Банды четырех» композитной схеме:

классы по уходу за детьми не должны быть выведены из класса Parent. Вместо этого классы Child и Parent должны реализовывать тот же интерфейс, назовем его IAlgorithm. Этот интерфейс должен иметь чистый virtual метод start() ...

Ниже приведен пример (с использованием C++ 11 auto и диапазон на основе цикл):

#include <iostream> 
#include <vector> 

/* parents and children implement this interface*/ 
class IAlgorithm { 
public: 
    virtual int start() = 0; 
}; 

class Parent : public IAlgorithm { 
private: 
    std::vector<IAlgorithm*> children; 

public: 
    void addChild(IAlgorithm* child) { 
     children.push_back(child); 
    } 

    int start() { 
     std::cout << "parent" << std::endl; 
     for (auto child: children) 
      child->start(); 
     return 0; 
    } 
}; 

class Child1 : public IAlgorithm { 
public: 
    int start() { 
     std::cout << "child 1" << std::endl; 
     return 1; 
    } 
}; 

class Child2 : public IAlgorithm { 
public: 
    int start() { 
     std::cout << "child 2" << std::endl; 
     return 2; 
    } 
}; 

class Child3 : public IAlgorithm { 
public: 
    int start() { 
     std::cout << "child 3" << std::endl; 
     return 3; 
    } 
}; 

int main() 
{ 
    Parent parent; 
    Child1 child_1; 
    Child2 child_2; 
    Child3 child_3; 

    parent.addChild(&child_1); 
    parent.addChild(&child_2); 
    parent.addChild(&child_3); 

    parent.start(); 

    return 0; 
} 

Выход:

parent 
child1 
child2 
child3 
+0

Спасибо, сэр! Отлично! – Jack

0

Родитель не может назвать дочерние методы, как правило. В этом случае вы создали класс как родительский тип, поэтому было бы довольно опасно называть что-то в ребенке, так как ребенок может принимать методы-члены или переменные, которые не находятся в родительском.

+0

Вы сказали «вообще», но может ли это быть сделано каким-то образом? – Jack

+0

Детский класс не может быть меньше размера памяти, чем родительский, поскольку он должен содержать все в родительском. Если дочерний элемент добавляет переменную-член, тогда ребенок будет больше. Когда вы создаете класс как родительский, он сохраняет только достаточное пространство для этого типа класса, и если ребенок пытается получить доступ к тому, что не находится в родительском, он будет читать мимо конца зарезервированного пространства памяти, что может вызвать крушение. – tloach

+0

Вы можете использовать reinterpret_cast для этого указателя для вызова функций-членов другого класса. Я могу почти 100% гарантировать, что вы этого не хотите. Вам нужно больше информации в своем вопросе, чтобы люди знали, как лучше всего перестроить ваш код, чтобы сделать эту работу. – tloach

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