C++ 解决实现困境的动态_cast
这件事让我沮丧了一个多星期。我已经在这个网站上浏览了很多关于dynamic_casting的帖子,但我仍然不确定实现这一点的最佳方法是什么 所以我有一个这样的基类:C++ 解决实现困境的动态_cast,c++,dynamic-cast,C++,Dynamic Cast,这件事让我沮丧了一个多星期。我已经在这个网站上浏览了很多关于dynamic_casting的帖子,但我仍然不确定实现这一点的最佳方法是什么 所以我有一个这样的基类: class baseClass { public: class recordBase { public: virtual ~recordBase(){} }; virtual ~baseClass()
class baseClass
{
public:
class recordBase
{
public:
virtual ~recordBase(){}
};
virtual ~baseClass() {};
virtual bool Allocate( int size,
recordBase *outRecord) = 0 ;
virtual bool Free(recordBase *allocRecord) = 0;
} ;
它有两个派生类。
像这样的派生类
class DerivedA : public baseClass
{
public:
class derivedRecordA : public baseClass::recordBase
{
public:
inline ~derivedRecordA(){} ;
someClass *obj1 ;
}
bool Allocate(int size,
baseClass::recordBase *outRecord);
bool Free(baseClass::recordBase *allocRecord) ;
}
我有一个类似的派生类“DerivedB”,它有自己的dervied记录库实现以及分配和释放函数
现在我终于有了一个使用上述基类的C类
class C
{
public:
baseClass *allocator ;
Allocate(int size) ;
Free(void) ;
}
现在是我的问题,基于某些条件,C类要么存储一个derivedA的分配器,要么存储一个derivedB的分配器
类C的分配函数如下所示
C::Allocate(int size)
{
//condition where DerivedA is needed
DerivedA::derivedRecordA recObj ;
if(allocator->Allocate(size, &recObj))
{
return true;
}
else return false ;
}
现在的问题是,我被迫在DerivedA::Allocate实现中使用动态强制转换,如下所示:
DerivedA::Allocate(int size, baseClass:recordBase *outRecord)
{
DerivedA::derivedRecordA *rec = dynamic_cast< DerivedA::derivedRecordA *>(outRecord) ;
//allocate mem and store info in 'rec'
return true ;
}
DerivedA::Allocate(整数大小,基类:recordBase*outRecord)
{
DerivedA::derivedRecordA*rec=动态播放(outRecord);
//分配mem并在“rec”中存储信息
返回true;
}
如何避免在此处使用动态_casting。这个问题有没有更干净的解决办法 有一个更干净的解决方案,它在baseRecord上使用一个虚拟函数,该函数被适当地重写
如果这不合适,检查
typeid
并在成功时使用static\u cast
可能比dynamic\u cast
更快,即使它是坏耦合。基类设计存在问题,这就是为什么在派生级别存在实现问题的原因
如果我有一个指向基类
实例的指针(不管它必须是什么实际类型),那么分配
方法的隐含约定是,我可以传递一个指向任何类型的基类::recordBase
的指针,一切都应该正常
如果派生类重写函数,则它们不应缩小函数用户的函数要求。这实际上意味着它们提供的覆盖不满足基类函数的接口。如果他们需要这样做,那么他们应该提供一个具有合适接口的不同功能
话虽如此,我还是希望有一个Allocate
函数来分配一个新对象。在这种情况下,您可以重写并返回指向专门化的指针(这称为协变返回类型)。例如,您可以覆盖:
virtual recordBase* Allocate(int size) = 0;
与
假设size
不应该是数组大小,并且您没有尝试返回指向派生对象数组的指针,这同样会给基类接口的用户带来问题
你真的需要用基类函数的契约和预期行为来扩展你的问题,这些重写应该是什么来获得更好的答案。为什么不为
recordBase
和derivedRecordA
使用struct
?此外,向内联定义添加inline
也是无用的。如果Allocate
始终需要对outRecord
执行特定操作,那么recordBase
应该通过其公共接口公开该功能。如果您只接受大多数派生类的对象DerivedA::deriverecorda
,在equality上使用typeid
和static\u cast
应该更快。无论如何,谨防过早的优化。您可能需要查看标准库并考虑使用模板来编码分配器知道的容器。我不认为我可以使用结构,因为ReordBASE派生到下面两个完全不同的实现。我面临的问题是动态_casting在这个实现中工作,但在free函数中失败。这是因为free函数从其他地方获取指向分配记录的指针Free(diffClassOBject->AllocationRecord())
此函数从其他类返回baseRecord类型的对象,但我的派生类无法使用动态强制转换将其解析为派生的基本记录,因此它会出现seg错误!问题是baseRecord派生到下面两个完全不同的实现,它们之间几乎没有任何共同之处
virtual derivedRecordA* Allocate(int size);