重写子类中的数组大小
Override array size in subclass
我有一个数组作为类的成员。在子类中,我想用不同的大小重新定义数组。我想这样做是因为我期望创建许多子类,每个子类只有它所需的数组大小,仅此而已。
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;
}
}
结果如下:
myFoo array size = 2
myBar array size = 4
fooCollection[0] array size = 2
fooCollection[1] array size = 2
fooCollection[0] ivar = 1
fooCollection[1] ivar = 3
我得到了,因为我将数组对象声明为类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> { ... };
当然,这只适用于所有东西都来自FooBase
的情况——也就是说,你没有一个来自Bar
的类,它需要不同的数组大小。
另外,正如在注释中所说的,如果你需要将它们保存在数组中,你需要存储指针。
Foo myFoo;
Bar myBar;
Foo * fooCollection[] = { &myFoo, &myBar };
哎呀,在那里我假设Bar
来自Foo
,它不再这样做了。如果您想要一个没有模板化的公共基类,则需要从另一个基类FooType
派生模板化类FooBase<Size>
,然后使用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];
};
然后:
FooType *fooCollection[] = { &myFoo, &myBar };
可以将数组定义为指针,然后在构造函数中new
它,在析构函数中delete
它。记住三法则,你就会没事的。
除非我完全误解了你这个程序的意图。
当您这样做:cout << sizeof(fooCollection[n].thisArray)/sizeof(int) << endl;
时,不可能知道thisArray
的大小,因为您没有使用实际的多态性。所以编译器假定fooCollection
中的所有元素都是简单的Foo
(静态绑定)。
从指针开始:
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];
};
这允许Foo成为多个类的公共"数组"接口,没有虚拟方法和堆栈分配数组。唯一的缺点是,我们必须插入Foo::arraySize,但这仍然是相对较小的成本(4/8字节在32/64位)。
- 为什么重载运算符"="动态数组的类上无法正常工作?C++
- std::数组派生类聚合初始化
- 包含不同大小静态数组的类的多个实例
- Getter 函数,用于在 2d 数组是类的数据成员时检索 2d 数组元素
- 如何将移动平均线写入数组列表类?
- 如何使用对象数组访问类中的变量?
- 未知大小的数组作为类成员,用于在运行时(对象创建时间)创建数组的对象
- 具有使用其他类对象的数组的类
- 函数指针数组的类模板参数推导适用于 clang,但不适用于 gcc
- 动态数组模板类:ostream&运算符友元函数的问题
- 如何在具有指向对象的指针数组的类中创建复制构造函数和析构函数,其中对象本身具有指向整数的指针数组
- 如何在C 中创建对象数组或类数组
- 如何将二维数组作为类中的私有变量,然后在构造函数中设置它
- 在标准C++中复制 C++/CLI 多维数组模板类
- 使用带有对象的数组调用类中的方法,错误"non-class type",c++
- 何时从数组删除类指针
- C 如何用数组在类中创建子类
- 具有2d数组的类中的否定运算符重载
- 如何为二维数组创建类
- C++:单个超类的数组子类