#include <iostream>
#include <memory>
#include <string>
struct IHandle {
virtual ~IHandle(void) {}
virtual std::string const & GetName(void) const = 0;
};
template <typename T> struct Handle : IHandle {
explicit Handle(std::shared_ptr<T> const & body) : mBody(body) {}
std::string const & GetName(void) const { return mBody->GetName(); }
private:
std::shared_ptr<T> mBody;
};
struct IFoo {
virtual ~IFoo(void) {}
template <typename T> void NVMethod(std::shared_ptr<T> const & body) {
VMethod(Handle<T>(body));
}
protected:
virtual void VMethod(IHandle const & handle) = 0;
};
struct FooEx1 : IFoo {
protected:
void VMethod(IHandle const & handle) {
std::cout << "引数の名前は " << handle.GetName() << " です。" << std::endl;
}
};
struct FooEx2 : IFoo {
protected:
void VMethod(IHandle const & handle) {
std::cout << "The name of argument is " << handle.GetName() << "." << std::endl;
}
};
struct Argument1 {
Argument1(std::string const & name) : mName(name) { }
std::string const & GetName(void) const {
return mName;
}
private:
std::string mName;
};
struct Argument2 {
Argument2(std::string const & name = std::string()) : mName(name) { }
std::string const & GetName(void) const {
static std::string const anon("Anon");
return mName.empty() ? anon : mName;
}
private:
std::string mName;
};
int main(void) {
std::shared_ptr<IFoo> p;
p = std::make_shared<FooEx1>();
p->NVMethod(std::make_shared<Argument1>("Bob"));
p = std::make_shared<FooEx2>();
p->NVMethod(std::make_shared<Argument2>());
return 0;
}