Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 解决实现困境的动态_cast_C++_Dynamic Cast - Fatal编程技术网

C++ 解决实现困境的动态_cast

C++ 解决实现困境的动态_cast,c++,dynamic-cast,C++,Dynamic Cast,这件事让我沮丧了一个多星期。我已经在这个网站上浏览了很多关于dynamic_casting的帖子,但我仍然不确定实现这一点的最佳方法是什么 所以我有一个这样的基类: class baseClass { public: class recordBase { public: virtual ~recordBase(){} }; virtual ~baseClass()

这件事让我沮丧了一个多星期。我已经在这个网站上浏览了很多关于dynamic_casting的帖子,但我仍然不确定实现这一点的最佳方法是什么

所以我有一个这样的基类:

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);