纯虚拟类(接口)和继承它的对象的内部数组分配

时间:2014-08-03 14:00:26

标签: c++ arrays class pure-virtual

我不确定我的想法是否可行,这是我想要实现的目标:

  1. 我正在开发一个C ++库,供其他开发人员(客户)使用。

  2. 库应该公开仅包含接口类的标头(纯虚拟类)。没别了。

  3. 开发人员将从公开的标题调用函数来分配对象(例如刚体),并释放它们。

  4. 我想有一个函数将返回经典的对象数组(使用new []分配),而不是链接列表或使用std ::

  5. 以下是它的样子:

    // exposed header (this is what developer will see)
    
    // interface class
    class someInterface
    {
    public:
        virtual void function1(void) = 0;
    };
    
    // public API to initialize array of objects and release it
    someInterface *NewSomeClassArray(unsigned int num);
    void ReleaseSomeClassArray(someInterface**a);
    

    // source compiled into static library (source not available to developer)
    
    // internal object type that inherits interface class
    class someClass : public someInterface
    {
    protected:
        unsigned int someVar; // some internal variable.
    public:
        someClass()
        {
            someVar = 10;
        }
        ~someClass()
        {
    
        }
        void function1(void)
        {
            printf("someVar = %d", someVar);
        }
    };
    
    
    // definition of public API functions
    
    // will allocate array of objects of someClass type and return pointer to first one
    someInterface *NewSomeClassArray(unsigned int num)
    {
        return new someClass[num];
    }
    
    // will release array of allocated objects and set it to point to NULL 
    // (simplified of course, no dynamic_cast etc. just as illustration)
    void ReleaseSomeClassArray(someInterface**a)
    {
        delete[] ((someClass*)(*a));
        (*a) = NULL;
    }
    

    因此,当开发人员将库链接到他的项目并包含标题时,他会执行以下操作:

    someInterface *test = NewSomeClassArray(2);
    test[0].function1();
    test[1].function1();
    ReleaseSomeClassArray(&test);
    

    但是,上面的内容在访问test [1]时会产生运行时违规(在iOS项目的XCode上测试)。

    这对我来说听起来合乎逻辑,因为“someInterface”的大小与“someClass”不同(someClass更大),因此offset [1]可能不指向右内存块。

    我很好奇是否有办法让这项工作让开发人员可以简单地迭代这样的对象数组?

    到目前为止,我在许多类似组织的库中看到过,你永远不会得到像这样的对象数组,而是链接列表或只是一个对象指针。有可能吗?

    P.S。在接受@ sp2danny的回答后(这是完全正确的),我想添加(如果有人需要它)一个可能的解决方法:

    // funciton in public API
    someInterface * GetSomeClassArrayMember(someInterface*a,unsigned int i);
    

    在图书馆内:

    someInterface * GetSomeClassArrayMember(someInterface*a,unsigned int i)
    {
        return &((someClass*)a)[i];
    }
    

    然后使用它:

    someInterface *test = NewSomeClassArray(2);
    GetSomeClassArrayMember(test,0)->function1();
    GetSomeClassArrayMember(test,1)->function1();
    ReleaseSomeClassArray(&test);
    

    通过这种方式,我可以满足客户端的请求,而不会在接口类中显示任何内容。

1 个答案:

答案 0 :(得分:1)

你要做的事情并非无足轻重;客户端代码不知道 实际对象的大小,因此不能将它们视为数组。

一种可能的解决方法,就是确保所有对象,包括基础,
具有相同的大小。

更好的解决方案是使用容器,迭代器,智能指针等