【发布时间】:2022-07-07 01:14:48
【问题描述】:
我想创建具有可变长度元素数组的对象,并让它们在基类/派生类意义上兼容。在 C 中,可以在 struct 的末尾放置一个不确定的数组,然后只需 malloc 对象以包含完整的数组:
struct foo {
int n;
double x[];
} ;
struct foo *foo1 = (foo *)malloc( sizeof( foo ) + sizeof( double[4] ) );
struct foo *foo2 = (foo *)malloc( sizeof( foo ) + sizeof( double[100] ) );
在 c++ 中,您似乎可以这样做:
template <unsigned I>
class foo {
public:
int n;
double x[I];
} ;
但是:
auto foo1 = new foo<4>( );
auto foo2 = new foo<100>( );
if (foo1 == foo2) cerr << "incompatible pointers";
你可以用一个通用的基类来做到这一点,但这有必要吗?我只想使用foo1 和foo2,每个对象都知道其数组的长度。
我的应用程序适用于运行 FreeRTOS 的 ESP32 微控制器。它具有有限的非虚拟 RAM 和稍微复杂的分配系统,因为各种内存块的功能不同(有些速度较慢,有些不能包含可执行代码,有些不能通过 DMA 访问等)所以分配一个对象的多个块(例如,在末尾使用std::vector 来表示double 的数组)变得复杂。
我在对象构造时知道double 数组的长度,但我希望标头和数组位于单个分配的内存块中(因此它可以具有我以后需要的特性)。
C 风格的做法会很好,但如果有 C++ 特性,比如对数组进行迭代(对于各种对象,每个对象都有不同数量的 doubles),那就太好了。另外,本机 C++ 解决方案将允许我在 x[] 数组中拥有对象,而不是在原始分配的内存中随意放置 new。所以,例如:
auto a[] = { new foo<5>( ), new foo<10>( ), new foo<15>( ) };
for (auto i : a)
for (auto j : i.x)
cout << log10( j ); // prints 40 logs of doubles
(我预计会有 C++ 语法错误,但希望它能传达这个想法。如果我可以将所有 foos 放入一个公共容器中,我可以弄清楚它的语法。)
【问题讨论】:
-
这就是
std::vector的用途。 -
为什么不
std::vector?我想你是有原因的。 -
如果你想比较两种不同类型的两个指针(很奇怪),你可以将它们转换为
void*。如果你想比较这两个对象(去掉那个无用的new),你必须告诉编译器你打算如何比较两个不同大小的数组,为你的类族提供一个模板化的operator== -
foo<4>和foo<100>是两个东西。您需要了解模板是什么。请改用std::vector>。 -
您的意思是“打印 40 个双打日志”吗?
标签: c++ arrays templates flexible-array-member