Как напечатать дату из базового класса + дополнительные данные из дочернего класса с помощью метода базового класса? - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть базовый класс с именем Animal, который содержит данные (возраст, вес и т. Д. c)

У меня есть дочерний класс, например, с именем Elephant, который содержит дополнительную переменную (размер клыка ) (и другие детские классы для разных животных)

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

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Вы можете использовать CRTP (Любопытно повторяющийся шаблон), чтобы распечатать детали Derived классов.

// Base class.
template<typename Derived>
class Base
{
protected:
    virtual void PrintDetails( std::ostream& stream ) = 0;
public:
    virtual ~Base( ) = default;

    void Print( ) 
    {
        auto derived{ static_cast<Derived*>( this ) };
        std::cout << "Details about base\n";
        derived->PrintDetails( std::cout );
    }
};

// Derived class.
class Derived : public Base<Derived> 
{    
private:
    friend Base<Derived>;

    void PrintDetails( std::ostream& stream ) override
    {        
        stream << "Details about derived\n";
    }
};

// Usage.
int main( ) 
{
    auto derived = new Derived;
    derived->Print( );
    delete derived;
}
0 голосов
/ 28 апреля 2020

Чтобы решить эту проблему, я бы предпочел использовать перегрузку операторов для стандартного оператора «вывода» << и использовать виртуальные функции с цепочкой базового класса для получения вывода из родительских классов.

Возможно, что-то похожее на

#include <iostream>

class Animal
{
public:
    virtual void output(std::ostream& out)
    {
        out << "output from the Animal class\n";
    }
};

class Mammal : public Animal
{
public:
    void output(std::ostream& out) override
    {
        Animal::output(out);
        out << "output from the Mammal class\n";
    }
};

class Elephant : public Mammal
{
public:
    void output(std::ostream& out) override
    {
        Mammal::output(out);
        out << "output from the Elephant class\n";
    }
};

// Overload the output operator to call the correct function for output
std::ostream& operator<<(std::ostream& out, Animal const& animal)
{
    animal.output(out);
    return out;
}

int main()
{
    Animal* animal = new Elephant;
    std::cout << *animal;
    delete animal;
}

Приведенный выше код должен напечатать

output from the Animal class
output from the Mammal class
output from the Elephant class

Это некоторое повторение, но не так много. И выполнение одной и той же вещи в нескольких местах обычно делает повторение неизбежным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...