#include <iostream>
#include <memory>

using namespace std;

class Content {
public:
    virtual void info() = 0;
};

class ContentA : public Content {
public:
    void info() override { cout << "Content A" << endl; }
    int serial() { return 123; }
    int num() { return 456; }
};

class ContentB : public Content {
public:
    void info() override { cout << "Content B" << endl; }
    int identifier() { return 789; }
};

class Container {
public:
    virtual shared_ptr<Content> content() = 0;
    virtual void info() = 0;
    void contentInfo() { content()->info(); }
};

class ContainerA : public Container {
public:
    ContainerA(shared_ptr<ContentA> content) : m_content(content) {}
    shared_ptr<Content> content() { return m_content; }
    void info() {
    	auto identifier = m_content->serial() * m_content->num();
    	cout << "Container A: " << identifier << endl;
    }
protected:
    shared_ptr<ContentA> m_content;
};

class ContainerB : public Container {
public:
    ContainerB(shared_ptr<ContentB> content) : m_content(content) {}
    shared_ptr<Content> content() { return m_content; }
    void info() {
    	cout << "Container B: " << m_content->identifier() << endl;
    }
protected:
    shared_ptr<ContentB> m_content; 
};

int main() {
	ContainerA containerA(make_shared<ContentA>());
	containerA.info();
	containerA.contentInfo();
	
	ContainerB containerB(make_shared<ContentB>());
	containerB.info();
	containerB.contentInfo();
	
	return 0;
}