i. problem description:
class derived
child of class base
. can not modify class base
. define constructors , assignement operators derived
constructed both instances of:
base
1derived
1n
non-polymorphic , not related typesfoo1
, ... ,foon
2.
1 construction both base
, derived
done using base
copy constructor.
2 construction of foo1
, ... , foon
done generic algorithm.
ii. possible solutions:
1. brute force:
n+1
separate constructors + n+1
separate assignment operators. absolutely not elegant. tons of useless code: n+1
methods declarations in header + n+1
methods implementations in source. power of templates not used.
2. template constructor type restriction
declare , define regular copy-constructor
derived::derived ( const base& object_reference ) { ... }
declare template constructor:
template<typename type> derived::derived ( const type& object_reference );
implement each of foo0
, ... , foon
template<> derived::derived<foo0> ( const foo0& object_reference ) { ... } ... template<> derived::derived<foo9> ( const foo9& object_reference ) { ... }
as result header contain 2 constructors , 2 assignment operators. have implement n+1
methods in source. believe there better solution anyway.
iii. not work:
1. separating `base` , `derived` others using `dynamic_cast`
template<typename type> derived::derived ( const type& object_reference ) { // line not compile since `foo0`, ... , `foon` non-polymorthic base* base_ptr = dynamic_cast <base*> (&object_reference); if ( base_ptr != nullptr ) { // construct `base` return; } // construct `foo0`, ... , `foon` }
2. separating `base` , `derived` others using `typeid`
template<typename type> derived::derived ( const type& object_reference ) { if ( typeid(typename) == typeid(foo0) || ... || typeid(typename) == typeid(foon) } { // construct `foo0`, ... , `foon` return; } else { // construct `base` // here should call `base` members `foo0`, ... , `foon` don't have // following line not compile // object_reference.some_method(); // , need cast "&object_reference" "base*" not possible // because `foo0`, ... , `foon` not polimorthic } }
iv. question:
is there efficient way, not described in section ii, solve problem?
you don't need use typeid
here:
2. separating `base` , `derived` others using `typeid`
just make 2 non-template ctors , 1 template ctor foo classes:
class derived : public base { public: derived(const derived&); derived(const base&); template<class foo> derived(const foo&); };