让我们假设我有类似的东西:
class A
{
public:
A(A* owner)
{
m_owner=owner;
if (dynamic_cast<B*>(this))
{
m_id=sm_bid;
sm_bid++;
}
else
{
m_id=sm_aid;
sm_aid++;
}
}
private:
int m_id;
A* m_owner;
static int sm_aid;
static int sm_bid;
};
A::sm_aid=0;
A::sm_bid=0;
class B: public A
{
B(A* owner) : A(owner) {}
};
不幸的是,dynamic_cast无法捕获它是一个B对象(当实例化时).这听起来合乎逻辑(因为超类中的构造函数在调用子类中的构造函数之前被调用.有没有办法实现这样的功能?
解决方法:
如果A是抽象类型,则可以使用基于标记的重载技术.
class B;
class C;
class A
{
public:
template<class Derived>
struct my_derived
{
using type = Derived;
};
protected:
explicit A(my_derived<B>)
{
// Do whatever you want when derived is B
}
explicit A(my_derived<C>)
{
// Do whatever you want when derived is C
}
private:
};
class B : A
{
public:
B() : A(A::my_derived<B>())
{
}
};
class C : A
{
public:
C() : A(A::my_derived<C>())
{
}
};
另一种方法是基于模板的编程,如AMA建议的那样.
但是虽然模板是C中的强大功能,但它们有自己的问题.它们无法在cpp文件中实现.它们导致代码膨胀,由于更大的代码大小会影响性能,这将导致更高的指令高速缓存未命中率.
所以我认为这种方法比具有运行时性能影响的RTTI更好,你必须在基类中声明一个虚函数,以及基于模板的方法.