2013-03-09 5 views
1

Я пытаюсь создать класс шаблона с несколькими дочерними элементами, которые переопределяют методы шаблона (я считаю, что я сделал это правильно). Затем мне нужна одна функция, которая может работать со всеми детьми.Использование наследования для общих функций

Например:

#include <iostream> 
using namespace std; 

class base{ 
public: 
    virtual void print(void){ 
     cout << "Base" << endl; 
    } 
}; 

class inherit_a : public base{ 
public: 
    virtual void print(void) override{ 
     cout << "inherit_a" << endl; 
    } 
}; 

class inherit_b : public base{ 
public: 
    virtual void print(void){ 
     cout << "inherit_b" << endl; 
    } 
}; 

void print_function(base item){ 
    item.print(); 
} 


int main(){ 
    inherit_a item_a; 
    print_function(item_a); 
    return(0); 
} 

Это печатает «база», как я ожидал бы, однако я хотел бы его использовать «метод печати s или inherit_b» inherit_a s метод печати, если inherit_b был приписан print_function. Что-то вроде этого возможно?

ответ

4

То, что вы ищете, называется полиморфизм подтипов; в C++ только ссылочные типы позволяют полиморфным вызовам функций virtual работать так, как вы ожидаете. Вы можете использовать ссылку:

или указатель:

void print_function(base* item){ 
    item->print(); 
} 

Что вы сделали передает объект по значению, копирование base части объекта только-это называется нарезка:

void print_function(base item){ 
    item.print(); 
} 

Обратите внимание, что с момента print() мем Функция ber не изменяет объект, его можно и должно быть объявлено const. Кроме того, (void) в списках параметров является стилем C и избыточным в C++; вместо этого используйте ().

virtual void print() const { 
    cout << "Base" << endl; 
} 

const является частью сигнатуры, поэтому подклассы должны также указать его:

virtual void print() const override { 
    cout << "inherit_a" << endl; 
} 

Тогда print_function() может принимать либо ссылку на const объекта:

void print_function(const base& item){ 
    item.print(); 
} 

Или в указатель на объект const:

void print_function(const base* item){ 
    item->print(); 
} 

Это документы, что print_function() также не изменяет его аргумент.

+0

большого спасибо, и спасибо за дополнительную информацию о Устах. Я смог заставить все работать. – user2150521

0

«Что-то вроде этого возможно?» - Yeap, и это называется polymorphism.

1

Проблема заключается в том, что вы принимаете значение base до print_function. Даже если вы передаете экземпляр inherit_a, он вызывает создание нового объекта, который набирается до base (называемый срезом объектов). В точке print_function выполняется это уже не значение inherit_a и, следовательно, не будет вызывать производный метод.

Что вы ищете является ссылкой на base, чтобы предотвратить разрезание и позволить значение для поддержания исходного типа

void print_function(base& item){ 
    item.print(); 
} 
Смежные вопросы