【发布时间】:2012-01-15 12:07:26
【问题描述】:
我有一个特殊的问题。我想在其中创建具有可变长度数组的类。出于局部性的原因,我不想在堆上分配数组(当我这样做时,代码会减慢 2 倍)。我不想使用虚函数,因为我不想为函数调用付费。以下代码有效(在我的编译器/平台上),但需要注意。
include <iostream>
include <boost/array.hpp>
struct Base
{
Base(size_t s):
size(s) {}
int& up(size_t i) { return *(reinterpret_cast<int*>((&size) + 1) + i); }
size_t size;
};
template<size_t sz>
struct Derived: public Base
{
boost::array<int, sz> data;
Derived(): Base(sz) {}
};
int main()
{
Derived<5> d5;
d5.data[2] = 1234;
Base* b = &d5;
std::cout << b->up(2) << std::endl;
}
这太丑了; reinterpret_cast<...> 是一个危险信号。此外,需要注意的是,如果我将 size_t 更改为 short unsigned(我猜编译器会填充类),这将失败。
所以问题是:有没有办法让这个便携?有没有办法从Base 确定第一个成员变量在其派生类中的位置?
【问题讨论】:
-
您测量虚函数调用的成本了吗?
-
这总是很难看的。
-
当
Derived具有固定大小时,为什么Base必须具有“未知”大小?看起来您不需要 VLA。 -
@Matteo 不,我没有。我承认它可能并不昂贵(我会仔细检查)。现在将其视为纯粹的学术练习。
-
我不太明白为什么这 a) 如此复杂 b) 您的代码的哪个方面是“动态的”。缓冲区大小似乎是一个模板参数,即编译时常量。如果这就是你想要的,这可能会容易得多......我一定错过了一些东西,但如果你能解释得更好一点,我将不胜感激。
标签: c++ memory alignment padding