我有一些C结构通过一些将c ++部分链接在一起的算法来使用。
在输入端有一个c ++结构,它继承自c结构以添加一些成员。在输出端,有一些组件也可能需要这些数据。
有没有一种安全的方法来检测这个C结构实际上是否是提到的c ++类?也许通过使c ++子类具有多态性并使用动态强制转换?
struct Cstruct{
int someData;
};
class CPPclass: public Cstruct{
CPPclass(){};
int someMoreData;
};
所以也许像是
class CPPclass: public Cstruct{
virtual ~CPPclass(){};
CPPclass(){};
int someMoreData;
};
void test(Cstruct* i_c){
auto cpp = dynamic_cast<CPPclass*>(i_c); // < does not work, because Cstruct is not polymorphic
if(cpp){
// da;
}
}
但也许?:
class CPPclassHelper: public Cstruct{
virtual ~CPPclassHelper(){};
CPPclassHelper(){};
int someMoreData;
};
class CPPclass: public CPPclassHelper{
virtual ~CPPclassHelper(){};
};
void test(Cstruct* i_c){
auto cpph = static_cast<CPPclassHelper*>(i_c);
auto cpp = dynamic_cast<CPPclass*>(cpph );
if(cpp){
// da;
}
}
答案 0 :(得分:1)
您可以自己维护类型信息。使用Cstruct
的基础CPPclass
的所有指针的静态集合。在CPPclass
的所有构造函数中插入基数并在析构函数中删除。然后可以使用对该集合的查找来实现安全强制转换。
以下是一个例子:
struct CPPclass: Cstruct{
CPPclass(){
bases.insert(this);
};
CPPclass(const CPPclass&){
bases.insert(this);
};
CPPclass(CPPclass&&){
bases.insert(this);
};
~CPPclass(){
bases.erase(this);
};
static CPPclass* safe_cast(Cstruct* c) {
auto it = bases.find(c);
return it == bases.end()
? nullptr
: static_cast<CPPclass*>(*it);
}
private:
static std::unordered_set<Cstruct*> bases;
};
用法:
int main() {
CPPclass cpp;
Cstruct c;
Cstruct* ptr_cpp = &cpp;
Cstruct* ptr_c = &c;
std::cout << CPPclass::safe_cast(ptr_cpp) << '\n'; // some address equal to &cpp
std::cout << CPPclass::safe_cast(ptr_c) << '\n'; // null
}