/******************************************************************************
Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, PHP, Ruby, Perl, Prolog, Javascript, Pascal, HTML, CSS, JS
Code, Compile, Run and Debug online from anywhere in world.
*******************************************************************************/
#include <stdio.h>
#include <memory>
using namespace std;
template <typename T>
class ihandle {
public:
virtual T* get();
};
template <typename T>
class ptr : public ihandle<T>
{
T* t;
public:
ptr(T* t = nullptr) : t(t) {}
T* get(){return t;}
};
template <typename T>
class handle
{
public:
ihandle<T>* h;
T* get(){return h->get();}
handle(ihandle<T>* h = nullptr) : h(h) {}
template <typename D>
handle(handle<D>& hd)
: h((ihandle<T>*)hd.h)
{
static_assert(is_base_of<T, D>::value, "error");
}
};
struct A {
virtual void talk() {printf("A\n");}
};
struct B : public A {
void talk() {printf("B\n");}
};
int main()
{
handle<B> hb(new ptr<B>(new B));
//hb.get()->talk(); // if uncomment, no segfault
handle<A> ha = hb;
ha.get()->talk();
return 0;
}