これはインタビュアーの質問に直接答えるものではありませんが、A と B の継承を操作する別の方法として、次のような方法があります。
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
//This concept was taken from a Going Native 2013 talk called "C++ Seasoning" given by Sean Parent
//
//Located here: (about 101 minutes into it)
//http://channel9.msdn.com/Events/GoingNative/2013/Cpp-Seasoning
//Polymorphism without inheritance.
//Permits polymorphism without using pointers or references,
//and allows them to be copied around easier (each instance is actually its own object) rather
//than accidentally shallow-copying when you wanted deep-copies.
//
//Every time Object::Print() is called, it calls
// Object::PrintableConcept::Print(), which virtually calls
// Object::PrintableModel<TYPE>::Print(), which calls your
// "derived" class that implements the Print() function, regardless
// of what that class inherits (if anything).
class Object //Class without inheritance or virtual.
{
public:
template<typename Type>
Object(Type instance) : self(std::make_shared<PrintableModel<Type>>(std::move(instance)))
{ }
//Calls the "inherited" function.
void Print() const
{
self->Print();
}
private:
struct PrintableConcept //The concept we want to polymorphably access.
{
virtual ~PrintableConcept() = default;
virtual void Print() const = 0;
};
//The class that concretely models the concept,
//and does the actual inheritting.
template<typename Type>
struct PrintableModel : public PrintableConcept
{
PrintableModel(Type instance) : data(std::move(instance)) { }
//Every time
void Print() const override
{
this->data.Print();
}
Type data;
};
//This should be a unique_ptr, but you also need to make sure
//you implement proper copy operators in this class and move support.
std::shared_ptr<PrintableConcept> self;
};
class Whatever
{
public:
void Print() const { std::cout << "Whatever\n" << std::endl; }
};
class SomethingElse
{
public:
void Print() const { std::cout << "SomethingElse\n" << std::endl; }
};
class WidgetThing
{
public:
void Print() const { std::cout << "WidgetThing\n" << std::endl; }
};
typedef std::vector<Object> Document;
int main()
{
Document document;
document.emplace_back(Whatever());
document.emplace_back(SomethingElse());
document.emplace_back(WidgetThing());
for(const auto &object : document)
{
object.Print();
}
return 0;
}
<<<コードを実行する>>>
実際には「オブジェクト」(または他のもの) から継承するクラスはありませんが、オブジェクトがテンプレートとしてアクセスする共通のインターフェイス ( ) をすべて実装しているため、ベクトルなどで相互に交換可能に使用できますがPrintableConcept
、オブジェクト自体はそうではありません。 't はテンプレートとならないので、どちらが別々の型になっObject<something>
ていたでしょう。Object<something-else>