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];
};