2015-03-18 6 views
1

У меня есть несколько объектов (классов), которые все наследуют от базового класса Structure. Эти объекты все печатаются по-разному, поскольку они имеют разные переменные-члены, но имеют общие функции.Оператор наследования C++ <<

Я хочу иметь список структур и печатать их без необходимости отбрасывать их обратно в их конкретный объект, т. Е. Structure -> Building.

Возможно ли это на C++?

class Structure 
{ 

}; 

class Building : public Structure 
{ 
public: 
    friend std::ostream& operator<<(std::ostream& o, const Building &b) 
    { 
     return o << b.m_windows.size() << b.m_doors.size(); 
    } 
protected: 
    Windows m_windows; 
    Doors m_doors; 
}; 

class Statue : public Structure 
{ 
public: 
    friend std::ostream& operator<<(std::ostream& o, const Statue &s) 
    { 
     return o << s.m_type; 
    } 
protected: 
    StatueType m_type; 
}; 

int main(int argc, char* argv[]) 
{ 
    Structure struct* = new Building(); 
    std::cout << struct << std::endl; 
    return 0; 
} 

Error: 
error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&' 
    std::cout << struct << std::endl; 

Edit:

Я изолировал вопрос в моем собственном коде, вот компилируется версия (C11). Проблема заключается в том, что я использую дальнейшее наследование и выход из моей команды:

CORRECT_VALUE<random address> 
8.8.8.80x804c504 

Я не знаю, почему он добавляет, что случайный адрес?

http://pastebin.com/81ubU0yX

+0

Возможно, вы имели в виду 'Structure * struct', а не' Structure struct * '? – emlai

+0

@zenith Будет ли компилироваться? :) –

+0

Не используйте struct as varaible name, потому что это зарезервированное слово. http://en.cppreference.com/w/cpp/keyword –

ответ

5

Создать виртуальную функцию вывода и вызвать его в operator <<. Переопределите эту функцию вывода в ваших производных классах.

class Structure 
{ 
public: 
    virtual ~Structure() {} 
    virtual std::ostream& StreamOut(std::ostream& o) const { return o; } 

    friend std::ostream& operator<<(std::ostream& o, const Structure &s) 
    { 
     return s.StreamOut(o); 
    } 
}; 

class Building : public Structure 
{ 
public: 
    virtual std::ostream& StreamOut(std::ostream& o) const 
    { 
     return o << m_windows.size() << m_doors.size(); 
    } 
protected: 
    Windows m_windows; 
    Doors m_doors; 
}; 

class Statue : public Structure 
{ 
public: 
    virtual std::ostream& StreamOut(std::ostream& o) const 
    { 
     return o << m_type; 
    } 
protected: 
    StatueType m_type; 
}; 

int main(int argc, char* argv[]) 
{ 
    std::unique_ptr<Structure> myStruct(new Building()); 
    std::cout << *myStruct << std::endl; 
} 
+0

Красивая, отлично работает. – critikull4

+0

@ critikull4 В общем случае это простые примеры [Inversion of Control] (http://en.wikipedia.org/wiki/Inversion_of_control) и, в частности, [Шаблон шаблона] (http://en.wikipedia.org/wiki/Template_method_pattern), очень полезные инструменты для понимания в целом для такого типа «базовый класс определяет алгоритмическую функциональность, подклассы определяют задачи реализации». – aruisdante

+0

@ Неужели вы можете посмотреть мой обновленный вопрос? – critikull4

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