Пример полиморфизма, работающего с структурой данных в C ++ на основе php-примера

Я изучаю полиморфизм, и я знаком с php.

Я наткнулся на этот отличный пример с https://stackoverflow.com/a/749738/80353 . воспроизводится ниже.

Как написать тот же код, но на C ++?

У меня возникла проблема с написанием этого самого, потому что я верю (может быть, ошибаюсь), что структуры данных на C ++ строги.

Вы должны иметь все элементы внутри связанного списка или массива в C ++ того же типа.

Поэтому я считаю, что вам нужно сохранить кошку и собаку в качестве базового класса в структуре данных.

Итак, как написать этот фрагмент кода php в фрагменте кода на C ++, который использует строгую структуру данных, что он может хранить только элементы из 1 типа данных?

class Animal { var $name; function __construct($name) { $this->name = $name; } } class Dog extends Animal { function speak() { return "Woof, woof!"; } } class Cat extends Animal { function speak() { return "Meow..."; } } $animals = array(new Dog('Skip'), new Cat('Snowball')); foreach($animals as $animal) { print $animal->name . " says: " . $animal->speak() . '<br>'; } 

Ну, вы можете использовать указатель с абстрактными классами, используя чистые виртуальные методы:

 class Polygon { public: virtual void setValue(int k) = 0; // Declaring our pure virtual method. }; class Rect : public Polygon { public: virtual void setValue(int k); = 0; // Declaring the pure virtual method again. }; Rect::setValue(int k) { // You must create a setValue() method for every class, since we made a pure virtual method. This is the Polymorphic part. // Code in here that setValue() method executes. int foo = a; std::cout << foo << std::endl; } 

Теперь вы можете получить доступ к методам, объявляющим указатели объектов.

 int main() { Polygon* pSomePolygon = nullptr; // Assuming using C++11. Rect* pRect = new Rect; // Declare our object. pSomePolygon = pRect; // Point our pointer to object 'pRect'. pSomePolygon->setValue(18); // Pointer accesses pRect and uses the pure virtual method. delete pRect; // Clean up! return 0; } 

Поскольку вы только просили об их хранении, я опустил реализацию Animal , Dog и Cat .

 vector< shared_ptr<Animal> > animals; animals.push_back( new Dog("Skip") ); animals.push_back( new Cat("Snowball") ); for( size_t i = 0; i< animals.size(); ++i ) cout << animals[i]->name << " says: " << animals[i]->speak() << endl; 

По существу вам нужно сохранить указатели на объекты. Проще говоря, shared_ptr<T> – это класс, который хранит указатель и удаляет его, когда он больше не ссылается.

Как кто-то, не знакомый с C ++, создайте файл index.cpp и заполните его следующим

 #include <iostream> #include <vector> #include <memory> using namespace std; class Animal { public: std::string name; Animal (const std::string& givenName) : name(givenName) {} virtual string speak () = 0; virtual ~Animal() {} }; class Dog: public Animal { public: Dog (const std::string& givenName) : Animal (givenName) { } string speak () { return "Woof, woof!"; } }; class Cat: public Animal { public: Cat (const std::string& givenName) : Animal (givenName) { } string speak () { return "Meow..."; } }; int main() { std::vector<std::unique_ptr<Animal>> animals; animals.push_back( std::unique_ptr<Animal>(new Dog("Skip")) ); animals.push_back( std::unique_ptr<Animal>(new Cat("Snowball")) ); for( int i = 0; i< animals.size(); ++i ) { cout << animals[i]->name << " says: " << animals[i]->speak() << endl; } } 

после этого скомпилируйте файл index.cpp следующей командой

 c++ index.cpp -std=c++11 -stdlib=libc++ 

вам нужно это из-за использования интеллектуальных указателей unique_ptr в коде.

наконец, вы можете выполнить скомпилированный исполняемый файл вывода, который должен быть a.out

 ./a.out