I have an class which inherit two interfaces:
class Multi : public IFoo, public IBar {
public:
virtual ~Multi();
// Foo part
virtual void fooMethod();
// ...
// Bar part
virtual void barMethod();
// ...
};
Unfortunately this class cannot be decomposed in two separate classes for each interface. In fact in class implementation those entities (Foo and Bar) are tightly coupled, but in future they could become separate.
Another one class wants to use Multi class, having a pointer to IFoo and IBar:
class ClientClass {
public:
ClientClass(); // constructor
// smth
private:
std::shared_ptr<IFoo> foo_;
std::shared_ptr<IBar> bar_;
};
In constructor I do something like:
ClientClass::ClientClass(){
auto pMulti = new Multi;
foo_ = std::shared_ptr<IFoo>(pMulti);
bar_= std::shared_ptr<IBar>(pMulti);
}
But each of those shared pointers has separate reference counter, and it leads to deleting already deleted pointer on class destruction, am I right?
How should I treat it?
What is best practics for such case?
ClientClass::ClientClass()
{
auto pMulti = std::make_shared<Multi>();
foo_ = pMulti;
bar_ = pMulti;
}
would ensure that they have the same reference counter. You can see it for yourself:
#include <iostream>
#include <memory>
class Base1{};
class Base2{};
class Derived : public Base1, public Base2 {};
int main()
{
auto derived = std::make_shared<Derived>();
std::shared_ptr<Base1> base1 = derived;
std::shared_ptr<Base2> base2 = derived;
std::cout << "base1 usecount = " << base1.use_count() << '\n';
std::cout << "base2 usecount = " << base2.use_count() << '\n';
std::cout << "derived usecount = " << derived.use_count() << '\n';
return 0;
}
produces:
base1 usecount = 3
base2 usecount = 3
derived usecount = 3
I don't know exactly what you want to do with those pointers, but an alternative solution may be to store a std::unique_ptr<multi> multi_; and have a couple of interface functions that static cast it to plain pointers or to references:
IFoo& ClientClass::get_ifoo() {
return *(static_cast<IFoo*>(multi_.get()));
}
IBar& ClientClass::get_ibar() {
return *(static_cast<IBar*>(multi_.get()));
}
As long as you don't pass those out from the class, and don't call delete[] on them it should be quite safe.
Related
Why can't one store an object as it's base virtual class ?
Consider the following example : It will segfault if Derived inherits virtually of Base
#include <iostream>
#include <memory>
class Base
{
public:
virtual ~Base() = default;
int baseInt = 42;
};
class Derived : public /* virtual */ Base // <<< Uncomment the virtual to get a segfault
{
public:
int derivedInt = 84;
};
int main()
{
Base *base_ptr = new Derived();
Derived *derived_ptr = reinterpret_cast<Derived *>(base_ptr);
std::cout << " baseInt is " << derived_ptr->baseInt
<< ", derivedInt is " << derived_ptr->derivedInt << std::endl; // segv on this line
}
The reinterpret_cast you used simply uses the Base pointer as if it were a Derived pointer.
Instead, this is one of the few situations where you should use a dynamic_cast.
The example in the documentation for dynamic_cast shows such a downcast.
Is the following approach good?
class TA { };
class TB : TA { };
std::shared_ptr<TA> spta;
spta.reset(new TB);
There's one problem with the code shown, TB must inherit publicly from TA. You have a shared_ptr<TA>, so the pointer you want to store in it must be convertible to TA, but with private inheritance, the base is inaccessible so your code will not compile.
class TA { };
class TB : public TA { };
Beyond this, the code has no errors and is well-behaved. Typically, when you perform polymorphic deletion of a derived class instance through a base class pointer, you need the base class' destructor to be virtual so the derived class destructor is called, but in case of shared_ptr this is not necessary. shared_ptr::reset is a function template that'll accept any Y* that is convertible to the managed pointer type. The same is true for shared_ptr's constructor template.
That being said, you should prefer making the base class' destructor virtual, especially if the classes involved have other virtual functions.
No, it is not for TA is private.
Moreover, as suggested in the comments, the destructor of the base class ought to be virtual. It is usually a good practice, for you cannot guarantee that instances of your classes will be used only with shared pointers.
To have it working, you must at least modify these lines:
class TA { };
class TB : TA { };
As it follows:
class TA { virtual ~TA() { } };
class TB : public TA { };
Those ones are good as the following example is good:
class TA { virtual ~TA() { } };
class TB : public TA { };
TA *spta = nullptr;
spta = new TB;
It mainly depends on what good means for you. It's legal, at least.
This is not an answer to the question, it is an attempt to clear up any confusion about shared_ptr's seemingly magical ability to avoid the use of a virtual destructor.
Here's a little demo program:
#include <iostream>
#include <memory>
struct A {
~A() { std::cout << __func__ << std::endl; }
void foo() { do_foo(); }
protected:
virtual void do_foo() {
std::cout << "A::" << __func__ << std::endl;
}
};
struct B : A {
~B() { std::cout << __func__ << std::endl; }
virtual void do_foo() override {
std::cout << "B::" << __func__ << " ";
A::do_foo();
}
};
using namespace std;
auto main() -> int
{
std::shared_ptr<A> p = std::make_shared<A>();
p->foo();
p = std::make_unique<B>();
p->foo();
cout << "deleting B:" << endl;
return 0;
}
expected output:
A::do_foo
~A
B::do_foo A::do_foo
deleting B:
~B
~A
Notice that the correct destructor was called when the B was destroyed at the end of main().
I read about the inheritance mechanism in C++ and about virtual functions.
according to my knowlendge (in all examples I have encountered), inherited methods had the same signature as the parent class'.
My question is the following:
I know that function default parameter value is not a part of function signature.
Can I define this value to be some constant in the parent Class virtual function, and in the derived class declare and implement the overriding method without this default value.
In this case, when I call the derived object's method using a pointer to parent class, will the function be called with/without this default initializion?
thanks
Default arguments are mostly syntactic sugar and get determined at compile time. Virtual dispatch, on the other hand, is a run-time feature. It would probably be least surprising to have that default parameter chosen that was defined alongside with the function that actually gets called but this is not possible (at least not without additional run-time overhead) for the reason stated above.
Therefore, the default parameter is selected by the compiler using the static type of the object a member function is called upon. Let's see an example.
#include <iostream>
#include <memory>
class Base
{
public:
virtual void
f(int a, int b = 1)
{
std::cout << "Base: a = " << a << ", b = " << b << "\n";
}
};
class Derived : public Base
{
public:
virtual void
f(int a = 1, int b = 2) override
{
std::cout << "Derived: a = " << a << ", b = " << b << "\n";
}
};
int
main()
{
std::unique_ptr<Base> base_as_base {new Base {}};
std::unique_ptr<Base> derived_as_base {new Derived {}};
std::unique_ptr<Derived> derived_as_derived {new Derived {}};
base_as_base->f(0); // Base: a = 0, b = 1
derived_as_base->f(0); // Derived: a = 0, b = 1
// derived_as_base->f(); // compiler error
derived_as_derived->f(0); // Derived: a = 0, b = 2
derived_as_derived->f(); // Derived: a = 1, b = 2
}
I agree that this is confusing. Please don't write code like this. Fortunately, there is a simple workaround. Apart from not using default parameters at all, we can use an idiom called non-virtual interfaces. The virtual function is made protected and not given any default parameters. It is then only called indirectly by a non-virtual function from the base class. That function can have all default parameters defined in a single place.
#include <iostream>
#include <memory>
class Base
{
public:
void
f(int a, int b = 1)
{
this->impl(a, b);
}
protected:
virtual void
impl(int a, int b)
{
std::cout << "Base: a = " << a << ", b = " << b << "\n";
}
};
class Derived : public Base
{
protected:
virtual void
impl(int a, int b) override
{
std::cout << "Derived: a = " << a << ", b = " << b << "\n";
}
};
int
main()
{
std::unique_ptr<Base> base_as_base {new Base {}};
std::unique_ptr<Base> derived_as_base {new Derived {}};
std::unique_ptr<Derived> derived_as_derived {new Derived {}};
base_as_base->f(0); // Base: a = 0, b = 1
derived_as_base->f(0); // Derived: a = 0, b = 1
derived_as_derived->f(0); // Derived: a = 0, b = 1
}
This is what I found from the C++ Draft Standard N3337:
8.3.6 Default arguments
10 A virtual function call (10.3) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default arguments from the function it overrides. [ Example:
struct A {
virtual void f(int a = 7);
};
struct B : public A {
void f(int a);
};
void m() {
B* pb = new B;
A* pa = pb;
pa->f(); // OK, calls pa->B::f(7)
pb->f(); // error: wrong number of arguments for B::f()
}
—end example ]
Coming to your question:
Can I define this value to be some constant in the parent Class virtual function,
Yes
and in the derived class declare and implement the overriding method without this default value
Yes.
However, when you call the function using a derived class pointer, you'll have to provide an argument. When you call the function using a base class pointer, you don't need to provide an argument.
I'm using CRTP to add a clone method to inherited classes, for example:
class Base
{
virtual ~Base() {};
virtual Base* clone() const = 0;
};
template<class Derived> class BaseCopyable : Base
{
public:
virtual Base* clone() const
{
return new Derived(static_cast<Derived const&>(*this));
}
};
class A : public BaseCopyable<A>;
class B : public BaseCopyable<B>;
etc...
But if I have a class that inherits from B, for example:
class differentB : public B;
Then clone() doesn't return an object of type differentB, it returns a B. Besides writing a new clone() method in differentB, is there some way to fix this?
Thanks for reading!
This is a rework of my answer to this question
Your intent is to have all the derived classes in your hierarchy
inherit cloneability (polymorphic copy) from their base class so
that you do not also need to provide each of them with an override
of clone(), but your attempted CRTP solution with class template
BaseCopyable can only only confer cloneability in this way upon
classes immediately derived from Base, and not upon classes derived
from such derived classes.
I do not think it is not possible to propagate cloneability right down an
arbitrarily deep hierarchy by confering cloneability "just once" at
the topmost concrete classes. You must explicitly confer it on each
concrete class, but you can do this via their base classes and
without repetitiously overriding clone(), by using a CRTP
template that relays cloneability from parent class to child in the
hierarchy.
Clearly, a CRTP template that fits this bill will differ from BaseCopyable
by requiring two template parameters: the parent type and the child type.
A C++03 solution is as illustrated by the following program:
#include <iostream>
// As base of D, this makes D inherit B and makes D cloneable to
// a polymorphic pointer to B
template<class B, class D>
struct cloner : virtual B
{
virtual B *clone() const {
return new D(dynamic_cast<D const&>(*this));
}
virtual ~cloner() {}
};
struct Base
{
virtual ~Base() {
std::cout << "I was a Base" << std::endl;
};
virtual Base* clone() const = 0;
};
struct A : cloner<Base,A> // A inherits Base
{
virtual ~A() {
std::cout << "I was an A" << std::endl;
};
};
struct B : cloner<Base,B> // B inherits Base
{
virtual ~B() {
std::cout << "I was a B" << std::endl;
};
};
struct DB : cloner<B,DB> // DB inherits B, Base
{
virtual ~DB() {
std::cout << "I was a DB" << std::endl;
};
};
int main()
{
Base * pBaseA = new A;
Base * pBaseB = new B;
Base * pBaseDB = new DB;
Base * pBaseCloneOfA = pBaseA->clone();
Base * pBaseCloneOfB = pBaseB->clone();
Base *pBaseCloneOfDB = pBaseDB->clone();
B * pBCloneOfDB = dynamic_cast<B*>(pBaseDB->clone());
std::cout << "deleting pBaseA" << std::endl;
delete pBaseA;
std::cout << "deleting pBaseB" << std::endl;
delete pBaseB;
std::cout << "deleting pBaseDB" << std::endl;
delete pBaseDB;
std::cout << "deleting pBaseCloneOfA" << std::endl;
delete pBaseCloneOfA;
std::cout << "deleting pBaseCloneOfB" << std::endl;
delete pBaseCloneOfB;
std::cout << "deleting pBaseCloneOfDB" << std::endl;
delete pBaseCloneOfDB;
std::cout << "deleting pBCloneOfDB" << std::endl;
delete pBCloneOfDB;
return 0;
}
The output is:
deleting pBaseA
I was an A
I was a Base
deleting pBaseB
I was a B
I was a Base
deleting pBaseDB
I was a DB
I was a B
I was a Base
deleting pBaseCloneOfA
I was an A
I was a Base
deleting pBaseCloneOfB
I was a B
I was a Base
deleting pBaseCloneOfDB
I was a DB
I was a B
I was a Base
deleting pBCloneOfDB
I was a DB
I was a B
I was a Base
Provided that all the classes involved are default constructible, B
need not be a virtual base of cloner<B,D> and you can remove the virtual
keyword from struct cloner : virtual B. Otherwise, B must be a virtual base
so that a non-default constructor of B can be called by a constructor of D,
although B is not a direct base of D.
In C++11, where we have variadic templates, you can do without virtual
inheritance altogether by furnishing cloner<B,D> with an "all-purpose"
template constructor through which it can forward arbitrary constructor
arguments from D to B. Here is an illustration of that:
#include <iostream>
template<class B, class D>
struct cloner : B
{
B *clone() const override {
return new D(dynamic_cast<D const&>(*this));
}
~cloner() override {}
// "All purpose constructor"
template<typename... Args>
explicit cloner(Args... args)
: B(args...){}
};
struct Base
{
explicit Base(int i)
: _i(i){}
virtual ~Base() {
std::cout << "I was a Base storing " << _i << std::endl;
};
virtual Base* clone() const = 0;
protected:
int _i;
};
struct A : cloner<Base,A>
{
explicit A(int i)
: cloner<Base,A>(i){}
~A() override {
std::cout << "I was an A storing " << _i << std::endl;
};
};
struct B : cloner<Base,B>
{
explicit B(int i)
: cloner<Base,B>(i){}
~B() override {
std::cout << "I was a B storing " << _i << std::endl;
};
};
struct DB : cloner<B,DB>
{
explicit DB(int i)
: cloner<B,DB>(i){}
~DB() override {
std::cout << "I was a DB storing " << _i << std::endl;
};
};
int main()
{
Base * pBaseA = new A(1);
Base * pBaseB = new B(2);
Base * pBaseDB = new DB(3);
Base * pBaseCloneOfA = pBaseA->clone();
Base * pBaseCloneOfB = pBaseB->clone();
Base * pBaseCloneOfDB = pBaseDB->clone();
B * pBCloneOfDB = dynamic_cast<B*>(pBaseDB->clone());
std::cout << "deleting pA" << std::endl;
delete pBaseA;
std::cout << "deleting pB" << std::endl;
delete pBaseB;
std::cout << "deleting pDB" << std::endl;
delete pBaseDB;
std::cout << "deleting pBaseCloneOfA" << std::endl;
delete pBaseCloneOfA;
std::cout << "deleting pBaseCloneOfB" << std::endl;
delete pBaseCloneOfB;
std::cout << "deleting pBaseCloneOfDB" << std::endl;
delete pBaseCloneOfDB;
std::cout << "deleting pBCloneOfDB" << std::endl;
delete pBCloneOfDB;
return 0;
}
And the output is:
deleting pA
I was an A storing 1
I was a Base storing 1
deleting pB
I was a B storing 2
I was a Base storing 2
deleting pDB
I was a DB storing 3
I was a B storing 3
I was a Base storing 3
deleting pBaseCloneOfA
I was an A storing 1
I was a Base storing 1
deleting pBaseCloneOfB
I was a B storing 2
I was a Base storing 2
deleting pBaseCloneOfDB
I was a DB storing 3
I was a B storing 3
I was a Base storing 3
deleting pBCloneOfDB
I was a DB storing 3
I was a B storing 3
I was a Base storing 3
What you can do is to propagate the base through the whole inheritance
hierarchy, but I don't think this will be particularly useful as for
every further derived class you now get a whole new hierarchy and all
the polymorphism is going to be for naught.
#include <iostream>
class Base
{
public:
virtual ~Base() {};
virtual Base* clone() const = 0;
};
template<class Derived> class BaseCopyable : Base
{
public:
virtual Base* clone() const
{
return new Derived(static_cast<Derived const&>(*this));
}
};
struct Default;
template<typename Self, typename Arg>
struct SelfOrArg {
typedef Arg type;
};
template<typename Self>
struct SelfOrArg<Self, Default> {
typedef Self type;
};
template<typename Derived = Default>
class A : public BaseCopyable< typename SelfOrArg<A<Derived>, Derived>::type >
{
};
class derivedA : A<derivedA> {
};
Although this still has the drawback of the broken return type for
BaseCopyable. With a classic virtual constructor idiom, you get
the ability to say something like:
void func(Derived& d) {
// thanks to covariant return types Derived::clone returns a Derived*
Derived* d2 = d.clone();
delete d2;
}
This wont be possible with your scheme, although easily possible
through adjusting the return type in BaseCopyable.
Just write a macro to get rid of the boilerplate :)
In C++, is there any way to query the type of an object and then use that information to dynamically create a new object of the same type?
For example, say I have a simple 3 class hierarchy:
class Base
class Foo : public Base
class Bar : public Base
Now suppose I give you an object cast as type Base -- which is in reality of type Foo.
Is there a way to query the type and use that info to later create new objects of type Foo?
Clone method
There is nothing provided by the language that queries type and lets you construct from that information, but you can provide the capability for your class hierarchy in various ways, the easiest of which is to use a virtual method:
struct Base {
virtual ~Base();
virtual std::auto_ptr<Base> clone(/*desired parameters, if any*/) const = 0;
};
This does something slightly different: clone the current object. This is often what you want, and allows you to keep objects around as templates, which you then clone and modify as desired.
Expanding on Tronic, you can even generate the clone function.
Why auto_ptr? So you can use new to allocate the object, make the transfer of ownership explicit, and the caller has no doubt that delete must deallocate it. For example:
Base& obj = *ptr_to_some_derived;
{ // since you can get a raw pointer, you have not committed to anything
// except that you might have to type ".release()"
Base* must_free_me = obj.clone().release();
delete must_free_me;
}
{ // smart pointer types can automatically work with auto_ptr
// (of course not all do, you can still use release() for them)
boost::shared_ptr<Base> p1 (obj.clone());
auto_ptr<Base> p2 (obj.clone());
other_smart_ptr<Base> p3 (obj.clone().release());
}
{ // automatically clean up temporary clones
// not needed often, but impossible without returning a smart pointer
obj.clone()->do_something();
}
Object factory
If you'd prefer to do exactly as you asked and get a factory that can be used independently of instances:
struct Factory {}; // give this type an ability to make your objects
struct Base {
virtual ~Base();
virtual Factory get_factory() const = 0; // implement in each derived class
// to return a factory that can make the derived class
// you may want to use a return type of std::auto_ptr<Factory> too, and
// then use Factory as a base class
};
Much of the same logic and functionality can be used as for a clone method, as get_factory fulfills half of the same role, and the return type (and its meaning) is the only difference.
I've also covered factories a couple times already. You could adapt my SimpleFactory class so your factory object (returned by get_factory) held a reference to a global factory plus the parameters to pass to create (e.g. the class's registered name—consider how to apply boost::function and boost::bind to make this easy to use).
The commonly used way to create copies of objects by base class is adding a clone method, which is essentially a polymorphic copy constructor. This virtual function normally needs to be defined in every derived class, but you can avoid some copy&paste by using the Curiously Recurring Template Pattern:
// Base class has a pure virtual function for cloning
class Shape {
public:
virtual ~Shape() {} // Polymorphic destructor to allow deletion via Shape*
virtual Shape* clone() const = 0; // Polymorphic copy constructor
};
// This CRTP class implements clone() for Derived
template <typename Derived> class Shape_CRTP: public Shape {
public:
Shape* clone() const {
return new Derived(dynamic_cast<Derived const&>(*this));
}
};
// Every derived class inherits from Shape_CRTP instead of Shape
// Note: clone() needs not to be defined in each
class Square: public Shape_CRTP<Square> {};
class Circle: public Shape_CRTP<Circle> {};
// Now you can clone shapes:
int main() {
Shape* s = new Square();
Shape* s2 = s->clone();
delete s2;
delete s;
}
Notice that you can use the same CRTP class for any functionality that would be the same in every derived class but that requires knowledge of the derived type. There are many other uses for this besides clone(), e.g. double dispatch.
There's only some hacky ways to do this.
The first and IMHO the ugliest is:
Base * newObjectOfSameType( Base * b )
{
if( dynamic_cast<Foo*>( b ) ) return new Foo;
if( dynamic_cast<Bar*>( b ) ) return new Bar;
}
Note that this will only work if you have RTTI enabled and Base contains some virtual function.
The second an neater version is to add a pure virtual clone function to the base class
struct Base { virtual Base* clone() const=0; }
struct Foo : public Base { Foo* clone() const { return new Foo(*this); }
struct Bar : public Base { Bar* clone() const { return new Bar(*this); }
Base * newObjectOfSameType( Base * b )
{
return b->clone();
}
This is much neater.
One cool/interesting thing about this is that
Foo::clone returns a Foo*, while Bar::clone returns a Bar*. You might expect this to break things, but everything works due to a feature of C++ called covariant return types.
Unfortunately covariant return types don't work for smart pointers, so using sharted_ptrs your code would look like this.
struct Base { virtual shared_ptr<Base> clone() const=0; }
struct Foo : public Base { shared_ptr<Base> clone() const { return shared_ptr<Base>(new Foo(*this) ); }
struct Bar : public Base { shared_ptr<Base> clone() const { return shared_ptr<Base>(new Bar(*this)); }
shared_ptr<Base> newObjectOfSameType( shared_ptr<Base> b )
{
return b->clone();
}
You can use e.g. typeid to query an object's dynamic type, but I don't know of a way to directly instantiate a new object from the type information.
However, apart from the clone approach mentioned above, you could use a factory:
#include <typeinfo>
#include <iostream>
class Base
{
public:
virtual void foo() const
{
std::cout << "Base object instantiated." << std::endl;
}
};
class Derived : public Base
{
public:
virtual void foo() const
{
std::cout << "Derived object instantiated." << std::endl;
}
};
class Factory
{
public:
static Base* createFrom( const Base* x )
{
if ( typeid(*x) == typeid(Base) )
{
return new Base;
}
else if ( typeid(*x) == typeid(Derived) )
{
return new Derived;
}
else
{
return 0;
}
}
};
int main( int argc, char* argv[] )
{
Base* X = new Derived;
if ( X != 0 )
{
std::cout << "X says: " << std::endl;
X->foo();
}
Base* Y = Factory::createFrom( X );
if ( Y != 0 )
{
std::cout << "Y says: " << std::endl;
Y->foo();
}
return 0;
}
P.S.: The essential part of this code example is of course the Factory::createFrom method. (It's probably not the most beautiful C++ code, since my C++ has gone a little rusty. The factory method probably shouldn't be static, on second thought.)
I used macros in my project to synthesize such methods.
I'm just researching this approach now, so I may be wrong, but here's an answer to your question in my code of IAllocable.hh. Note that I use GCC 4.8, but I hope 4.7 suits.
#define SYNTHESIZE_I_ALLOCABLE \
public: \
auto alloc() -> __typeof__(this) { return new (__typeof__(*this))(); } \
IAllocable * __IAllocable_alloc() { return new (__typeof__(*this))(); } \
private:
class IAllocable {
public:
IAllocable * alloc() {
return __IAllocable_alloc();
}
protected:
virtual IAllocable * __IAllocable_alloc() = 0;
};
Usage:
class Usage : public virtual IAllocable {
SYNTHESIZE_I_ALLOCABLE
public:
void print() {
printf("Hello, world!\n");
}
};
int main() {
{
Usage *a = new Usage;
Usage *b = a->alloc();
b->print();
delete a;
delete b;
}
{
IAllocable *a = new Usage;
Usage *b = dynamic_cast<Usage *>(a->alloc());
b->print();
delete a;
delete b;
}
}
Hope it helps.
In C++, is there any way to query the type of an object...
Yes, use typeid() operator
For example:
// typeid, polymorphic class
#include <iostream>
#include <typeinfo>
#include <exception>
using namespace std;
class CBase { virtual void f(){} };
class CDerived : public CBase {};
int main () {
try {
CBase* a = new CBase;
CBase* b = new CDerived;
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
cout << "*a is: " << typeid(*a).name() << '\n';
cout << "*b is: " << typeid(*b).name() << '\n';
} catch (exception& e) { cout << "Exception: " << e.what() << endl; }
return 0;
}
Output:
a is: class CBase *
b is: class CBase *
*a is: class CBase
*b is: class CDerived
If the type typeid evaluates is a pointer preceded by the dereference operator (*), and this pointer has a null value, typeid throws a bad_typeid exception
Read more.....
class Base
{
public:
virtual ~Base() { }
};
class Foo : public Base
{
};
class Bar : public Base
{
};
template<typename T1, typename T2>
T1* fun(T1* obj)
{
T2* temp = new T2();
return temp;
}
int main()
{
Base* b = new Foo();
fun<Base,Foo>(b);
}
When there are extremely many classes deriving from the same base class then this code will save you from having to include clone methods every class. It's a more convenient way of cloning that involves templates and an intermediate subclass. It's doable if the hierarchy is shallow enough.
struct PureBase {
virtual Base* Clone() {
return nullptr;
};
};
template<typename T>
struct Base : PureBase {
virtual Base* Clone() {
return new T();
}
};
struct Derived : Base<Derived> {};
int main() {
PureBase* a = new Derived();
PureBase* b = a->Clone(); // typeid(*b) == typeid(Derived)
}