C++ 重写子类中的数组大小

C++ 重写子类中的数组大小,c++,arrays,inheritance,C++,Arrays,Inheritance,我有一个数组作为类的成员。在子类中,我想用不同的大小重新定义数组。我之所以想这样做,是因为我期望生成许多子类,每个子类只具有它所需的数组大小,而没有更多 class Foo { Foo() {ivar = 1}; int thisArray[2]; int ivar; } class Bar : public Foo { Bar() {ivar = 3}; int thisArray[4]; } int main() { Foo myFoo;

我有一个数组作为类的成员。在子类中,我想用不同的大小重新定义数组。我之所以想这样做,是因为我期望生成许多子类,每个子类只具有它所需的数组大小,而没有更多

class Foo
{
    Foo() {ivar = 1};
    int thisArray[2];
    int ivar;
}

class Bar : public Foo
{
    Bar() {ivar = 3};
    int thisArray[4];
}

int main()
{
    Foo myFoo;
    Bar myBar;

    Foo fooCollection[] = {myFoo,myBar};

    cout << "myFoo array size = " << sizeof(myFoo.thisArray)/sizeof(int) << endl;
    cout << "myBar array size = " << sizeof(myBar.thisArray)/sizeof(int) << endl;

    for (int n=0;n<2;n++)
    {
        cout << "fooCollection[" << n << "] array size = ";
        cout << sizeof(fooCollection[n].thisArray)/sizeof(int) << endl;
    }
    for (int n=0;n<2;n++)
    {
        cout << "fooCollection[" << n << "] ivar = ";
        cout << fooCollection[n].ivar << endl;
    }

}
我明白了,因为我将数组对象声明为类
Foo
的对象,在该范围内引用
myBar
将引用
myBar
,就好像它是
Foo
一样,并因此将
thisArray
的大小解释为等于2。我也理解为什么
ivar
会这样出现


是否有方法影响
Bar
类中
thisArray
的大小,以便在
Foo
对象数组中识别其“正确”大小?我会使用矢量,但它们在arduino平台上不友好。我也可以简单地在Foo类中创建一个大小为100的数组,但我正在尝试意识到内存分配。

您可以将数组定义为指针,然后使用构造函数新建它,然后在析构函数中删除它。记住三条规则,你会没事的


除非我完全误解了您对本程序的意图。

您可以模板化基类:

template <size_t Size>
class FooBase
{
    // etc....
    int thisArray[Size];
};

class Foo : public FooBase<2> { ... };

class Bar : public FooBase<4> { ... };
哎呀,在这里,我假设
Bar
源自
Foo
,现在它不再这样做了。如果您想要一个没有模板化的公共基,那么需要从另一个基
FooType
派生模板化类
FooType
,现在使用
FooType
的数组。我想那会管用的

class FooType {
  public:
      // etc...
      virtual size_t GetSize() const = 0;
};

template <size_t Size>
class FooBase : public FooType
{
  public:
    // etc...
    virtual size_t GetSize() const { return Size; }

  protected:
    // etc....
    int thisArray[Size];
};

当您这样做时:
cout我的意见是不允许基类是一个具体的类:

  • 让基类是一个抽象类,为 数组(数组大小、对数组的读写)

  • 让阵列的构造和销毁由 派生类

  • 这样,每个派生类都可以根据需要选择其数组的长度

    代码草图:

    class foo {
      public:
        virtual size_t array_size() const = 0;
        virtual int *  array_base() const = 0;
        int array_get( size_t index ) const {
          array_verify_index( index );
          return *( array_base() + index );
        }
        void array_set( size_t index, int value ) {
          array_verify_index( index );
          *( array_base() + index ) = value;
        }
      private:
        void array_verify_index( size_t index ) const {
          assert( index < array_size() );
        }
    };
    
    class bar : public foo {
      public:    
        bar() {
           array_base = new int[ BarArraySize ];
        }
        ~bar() {
          delete [] array_base;
        }
        virtual size_t array_size() const {
          return BarArraySize;
        }
        virtual int * array_base() const {
          return array_base;
        }
      private:
        int * array_base;
    };
    
    class-foo{
    公众:
    虚拟大小\u t数组\u size()常量=0;
    虚拟整数*数组_base()常量=0;
    int数组获取(大小索引)常量{
    数组\验证\索引(索引);
    返回*(数组_base()+索引);
    }
    无效数组集合(大小索引,int值){
    数组\验证\索引(索引);
    *(数组_base()+索引)=值;
    }
    私人:
    无效数组校验索引(大小索引)常量{
    断言(索引
    我很清楚我迟到了两年,我想添加另一个选项-对于那些在没有虚拟方法或新操作员的情况下寻求此问题答案的人:

    class Foo
    {
    protected:
        // Can only be constructed by Bar, or other derived type.
        Foo(int* _array, size_t _size) :
            array(_array), 
            arraySize(_size)
        {};
    private:
        int* array;
        size_t arraySize;
    };
    
    template<size_t Size>
    class Bar : public Foo
    {
    public:
        Bar() : Foo(arrayData, Size) {};
    private:
        int arrayData[Size];
    };
    
    class-Foo
    {
    受保护的:
    //只能由Bar或其他派生类型构造。
    Foo(int*\u数组,大小\u t\u大小):
    数组(_数组),
    阵列化(_大小)
    {};
    私人:
    int*数组;
    大小排列;
    };
    模板
    分类栏:公共食品
    {
    公众:
    Bar():Foo(arrayData,Size){};
    私人:
    int arrayData[大小];
    };
    

    这允许Foo成为多个类的公共“数组”接口,没有虚拟方法,也没有堆栈分配的数组。唯一真正的缺点是,我们必须插入Foo::arraySize,但这仍然需要相对较小的成本(32/64位上的4/8字节)。

    不相关但很重要:查找“构造函数初始值设定项列表”。是否有理由需要使用多态性?是否有理由不希望使用STL容器来为您处理所有这些重新分配?使用指针数组
    Foo*fooCollection[]
    Bar
    对象更大。我的基类有很多成员,我希望在子类中继承这些成员。我唯一真正想改变的是成员数组的大小。你也可以让模板类从一个公共基派生出来,不是吗?是的,我相信是这样,我在回答中对此做了评论,当你想在数组中存储所有这些实例时,你需要一个指针。你建议的语法给了我错误,例如当我尝试输入
    FooType*集合[]时,“FooType没有名为'thisArray'的成员变量”…
    我将进一步研究模板,因为您试图颠覆面向对象的原则。在
    FooType
    上创建一个名为
    GetSize()
    的纯虚拟函数,并在模板类中实现它以返回
    Size
    。我已经编辑了我答案底部的代码来说明问题。帕迪,我实现了你的更改,它们成功了。模板可能是一种很好的方法。非常感谢!谢谢你的意见。我将研究如何创建更抽象的基类。这似乎适合我的问题。谢谢!我实施了这一战略,它符合我的目的。
    FooType *fooCollection[] = { &myFoo, &myBar };
    
    Foo * fooCollection[] = { &myFoo, &myBar };
    
    virtual int size() {return sizeof(thisArray);}
    
    cout << fooCollection[n]->size()/sizeof(int) << endl;
    
    class foo {
      public:
        virtual size_t array_size() const = 0;
        virtual int *  array_base() const = 0;
        int array_get( size_t index ) const {
          array_verify_index( index );
          return *( array_base() + index );
        }
        void array_set( size_t index, int value ) {
          array_verify_index( index );
          *( array_base() + index ) = value;
        }
      private:
        void array_verify_index( size_t index ) const {
          assert( index < array_size() );
        }
    };
    
    class bar : public foo {
      public:    
        bar() {
           array_base = new int[ BarArraySize ];
        }
        ~bar() {
          delete [] array_base;
        }
        virtual size_t array_size() const {
          return BarArraySize;
        }
        virtual int * array_base() const {
          return array_base;
        }
      private:
        int * array_base;
    };
    
    class Foo
    {
    protected:
        // Can only be constructed by Bar, or other derived type.
        Foo(int* _array, size_t _size) :
            array(_array), 
            arraySize(_size)
        {};
    private:
        int* array;
        size_t arraySize;
    };
    
    template<size_t Size>
    class Bar : public Foo
    {
    public:
        Bar() : Foo(arrayData, Size) {};
    private:
        int arrayData[Size];
    };