0

简单的例子:

template <class P> class MyT
{
    struct Item
    {
    public:
        Item() {}
        P *pData;
        Item *next;
    };
    Item *head;
public:
    ...adding etc..
    P* operator [](int index)
    {
       See question below:
    }
};

我能否以某种方式确保以某种方式分配“项目”,以便我可以按如下方式计算偏移量:(@Steve :) 也许这里不太清楚;我需要的是一种快速简便的方法来获得该项目,而无需遍历 10000 个下一个。

Item *pi = head + (sizeof(Item) * (index - 1));

(更清楚?)解释我的意思

4

5 回答 5

1

我猜你需要的是一个 std::list 或 std::vector。

但是,如果您为 Items 分配了顺序内存并且 head 指向开始以及 Yossarian 建议的修改,那么您正在尝试的操作将起作用。

如果超出此限制,您可以在初始化时预先分配,分配更多并将您的内容复制到该区域,释放现有的。

注意:所有这些东西都包装在 std 容器中。

于 2010-09-13T07:54:13.820 回答
1

取决于您在“添加等”中“等”的含义。

如果“etc”包括“removing”,那么你有一个明显的问题,如果你删除了列表中间的一些东西,那么为了保持索引,你必须向下移动它之后的所有内容,这意味着更新所有next指针。

我想也许你把你的例子简化得太多了。如果您需要连续存储,请使用向量(或者P,或者Item如果Item您删除了有用的东西)。如果你有连续的存储,那么拥有一个next指针没有任何好处,因为你可以Item通过将 1 加到中来计算它this(然后检查一个边界以确保你没有到达终点)。

如果您绝对需要公共next指针字段,因为它是您正在实现的某些接口的一部分,您无法更改,那么您可以在复制构造函数和operator=for中更新它Item,并且该接口最好禁止客户端写入它。

没有办法告诉内存分配器为单独的分配分配连续的存储空间,如果那是你所要求的。那怎么行?如果你来分配的时候,“下一个”地址已经被占用了怎么办?如果分配器为自己的控制结构(几乎所有通用分配器都这样做)施加了一些开销,那么分配 anItem需要的不仅仅是sizeof(Item)字节怎么办?您可以使用固定大小的分配器在一段时间内获得您想要的行为,但最终它需要一个新块,或者您删除某些内容,并且关系不再成立。

于 2010-09-13T09:11:32.617 回答
1

可以通过特殊的 gcc 关键字强制“内存边界”

http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes

看“对齐”

于 2010-09-13T20:32:12.443 回答
0

如果我正确理解您的问题,您需要覆盖operator newforItem并让分配器预先分配足够的内存来存储Item您将需要的所有 s (这在一般情况下是不可能的,但在您的特定情况下可能是可能的)。然后,每当更新 anItem时,分配器将返回预分配块中的下一个插槽。

所有这些看起来都不现实,简单的解决方案是使用std::vector.

于 2010-09-15T08:20:55.320 回答
-2
Item* pi = (head + (index - 1));

做这项工作。顺便说一句,你确定要这样做吗?struct Item看起来像链表结构(包含next)。

于 2010-09-13T07:47:18.380 回答