【发布时间】:2020-01-06 04:58:59
【问题描述】:
注意:我不是指指向 OBJECT 或 INSTANCE 的指针,而是指指向 CLASS 的指针
我把它放在顶部是因为我知道如果我不这样做,人们会告诉我我可以做到
class MyClass;
MyClass* pointerToMyClass = new MyClass(); // Ta-da! pointer to class!
这不是我要找的。我想创建一个指向类类型本身的指针,有点像函数指针,但是对于一个类。
为了更清楚我的要求,这里有一些代码大致展示了我在寻找什么。
class MyClass; // real Class
class MyDerived : public MyClass; // derived class
class * ClassPointer = &MyClass; // pointer to my class
MyClass * instanceOfPointer = new ClassPointer(); // now makes an instance of MyClass
ClassPointer = &MyDerived; // pointer to derived class
MyClass * instance2 = new ClassPointer(); // now makes an instance of DerivedClass
有点像 typedef,但更具动态性。
我还希望能够制作一个类指针向量。目前,我正在使用类函数clone() 来破解我需要的行为,该函数返回一个指向基类的新指针,但我并不特别喜欢这种方法。
在 C++ 中有这样的可能吗?
编辑: 我正在使用它的当前问题是多态网络协议。 有一个基础数据包类:
class packet{
int id=0;
virtual packet* read(); // read packet type into id
virtual packet* clone(){ return new packet(); }
};
然后是多个派生数据包:
class packet1 : public packet{
int id=1
packet* read(); // do packet specific reading
packet * clone(){ return new packet1(); }
};
class packet2 : public packet{
int id=2
packet* read(); // do packet specific reading
packet * clone(){ return new packet21(); }
};
class packet3 : public packet{
int id=3
packet* read(); // do packet specific reading
packet * clone(){ return new packet3(); }
};
那么你需要做的就是读取一个数据包
packet* array[] = { new packet(), new packet1(), new packet2(), new packet3() }; // array of packets, this should be class* if possible
packet type = packet();
type.read(); // read type from network
packet* data = array[type.id].clone(); // pick derived class based on type
data->read(); // read specific packet from network
packet*[] 将替换为 class*[] 以避免必须使用 clone()。
这是一个简化但可行的示例。
【问题讨论】:
-
没有。这不可能。但是您可以解释您遇到的问题并寻求可能的设计解决方案。但是,由于缺少反射,并且模板元编程困难且不可读,C++ 中存在一些限制。
-
这甚至没有意义。想想你会如何使用它,用一种硬类型的语言。您可能想看看模板。
-
您能否解释一下您不喜欢的
clone方法,以便我们知道您想要哪种解决方案?是否需要有一个类的实例? (因为如果是这样,那很容易解决。) -
你可以玩
std::decltype,但这似乎不切实际。模板就是这样做的方法。 -
由于您唯一需要做的就是默认构造它,因此您可以使用静态函数。 (这是一件好事,因为如何确定每个派生类都有一个公共的默认构造函数?)
template<typename T> T* make<T>() { return new T(); },然后你可以做到using packet_maker = packet*(*)(); *packet_maker[] array={make<packet>, make<packet1>, make<packet2>, make<packet3> };