我创建了一些对我来说很奇怪的代码,但似乎做了我想要的。但是,我不确定它的平台独立性或它的安全性,或者是否有更简单的方法来做我想要的事情。
我正在阅读奇怪的重复模板程序(on wikipedia),并且有一个类计数器的示例代码,它允许每个派生类通过从基础继承来跟踪已创建的实例数。功能。
我一直在寻找让派生类引用公共对象(通过指针)的方法,而不必添加静态变量并为我创建的每个新类定义虚函数。 (我正在计划创建相当多的派生类。)但是,派生类因为它们是使用模板创建的,因此被认为与基础不同,因此无法将它们隐式转换为基本指针。
Dynamic_cast和static_cast不起作用,所以我尝试了reinterpret_cast,以获得乐趣,看看有什么行为。它最终显示了基类中的静态变量,这不是我想要的,但它让我想起了之前我对静态和虚函数的经验(长篇故事)。我在基类中编写了一个虚函数,虚函数报告了派生类的正确变量,多态。
它起作用,至少根据codepad.org,但我仍然不确定它的平台一致性或在这种情况下reinterpret_cast的安全性。有经验的人可以说清楚为什么会有效吗?
这是我的代码。它看起来像维基百科的示例代码,因为它就是它原来的样子。
#include <iostream>
using namespace std;
template <typename T>
class counter
{
public:
static int separateObject;
virtual void printStatic(){
cout << this->separateObject << endl;
}
};
template <typename T> int counter<T>::separateObject( 0 );
class X : public counter<X>
{
// ...
};
class Y : public counter<Y>
{
// ...
};
typedef counter<void*>* voidcounter;
int main(){
X* counterX = new X;
Y* counterY = new Y;
counterX->separateObject = 9001;
counterY->separateObject = 42;
cout << "Object Xs value is: " << counterX->separateObject << endl;
cout << "Object Ys value is: " << counterY->separateObject << endl;
voidcounter polycount = reinterpret_cast<voidcounter>(counterX);
polycount->printStatic();
polycount = reinterpret_cast<voidcounter>(counterY);
polycount->printStatic();
return 0;
}
答案 0 :(得分:1)
我一直在寻找让派生类引用公共对象的方法
然后不要使用CRTP。 CRTP适用于您需要所有基类型不常见的情况(这是允许每种类型拥有它自己的计数器的原因)。这完全是它的100%。如果需要共享公共库,请使用普通的虚拟基类。您无法使用static_cast
或dynamic_cast
,因为它们没有共同基础。您使用reinterpret_cast
所做的事情是非常不安全的,因为它是未定义的行为。
class shared_counter_base {
virtual ~shared_counter_base(){}
virtual void printStatic()=0;
};
template <typename T>
class counter : shared_counter_base
{
public:
static int separateObject;
virtual void printStatic() {
cout << this->separateObject << endl;
}
};
template <typename T> int counter<T>::separateObject( 0 );
class X : public counter<X>
{
// ...
};
class Y : public counter<Y>
{
// ...
};
int main(){
X* counterX = new X;
Y* counterY = new Y;
counterX->separateObject = 9001;
counterY->separateObject = 42;
cout << "Object Xs value is: " << counterX->separateObject << endl;
cout << "Object Ys value is: " << counterY->separateObject << endl;
shared_counter_base polycount = counterX;
polycount->printStatic();
polycount = counterY;
polycount->printStatic();
return 0;
}