一、问题描述:
班级Derived
是班级的孩子Base
。你不能修改类Base
。定义构造函数和赋值运算符,Derived
以便可以从以下实例构造它:
Base
1Derived
1N
非多态且不相关的类型Foo1
,...,FooN
2。
1从两者构造Base
并Derived
使用Base
复制构造函数完成。
2Foo1
所有, ...的构造FooN
是由通用算法完成的。
二、可能的解决方案:
1.蛮力:
N+1
单独的构造函数 +N+1
单独的赋值运算符。绝对不优雅。大量无用的代码:N+1
标头中的方法声明 +N+1
源中的方法实现。未使用模板的力量。
2. 有类型限制的模板构造函数
声明和定义常规复制构造函数
Derived::Derived ( const Base& object_reference ) { ... }
声明模板构造函数:
template<typename type>
Derived::Derived ( const type& object_reference );
为每个Foo0
, ... ,FooN
template<>
Derived::Derived<Foo0> ( const Foo0& object_reference ) { ... }
...
template<>
Derived::Derived<Foo9> ( const Foo9& object_reference ) { ... }
因此,标头将仅包含两个构造函数和两个赋值运算符。但是我们必须N+1
在源代码中实现方法。无论如何,我相信有更好的解决方案。
三、什么不起作用:
1. 使用 `dynamic_cast` 将 `Base` 和 `Derived` 与其他人分开
template<typename type>
Derived::Derived ( const type& object_reference )
{
// This line will not compile since `Foo0`, ... , `FooN` are non-polymorthic
Base* base_ptr = dynamic_cast <Base*> (&object_reference);
if ( base_ptr != nullptr )
{
// Construct from `Base`
return;
}
// Construct from `Foo0`, ... , `FooN`
}
2. 使用 `typeid` 将 `Base` 和 `Derived` 与其他人分开
template<typename type>
Derived::Derived ( const type& object_reference )
{
if
(
typeid(typename) == typeid(Foo0)
||
...
||
typeid(typename) == typeid(FooN)
}
{
// Construct from `Foo0`, ... , `FooN`
return;
}
else
{
// Construct from `Base`
// Here we should call `Base` members which `Foo0`, ... , `FooN` don't have
// so the following line will not compile
// object_reference.some_method();
// And we need to cast "&object_reference" to "Base*" what is not possible
// because `Foo0`, ... , `FooN` are not polimorthic
}
}
四。问题:
有没有在第二节中没有描述的有效方法来解决这个问题?