使用对象或指向对象的指针作为类成员和内存分配

发布于 2024-11-05 15:33:24 字数 468 浏览 0 评论 0原文

这里提出了类似的问题:

作为对象的类成员 -指针还是不指针? C++

所以我会保持简短。

假设我有一个包含三个 stl 向量的对象。我的想法是否正确,如果他们是班级的正式成员,他们的记忆将是整个对象的“在一起”?例如,我的记忆看起来像 10 个块向量 A,5 个块向量 B,然后是 15 个块向量 C。然后,一旦我将更多对象插入向量 A,以便空间用完包括向量 B 和 C 在内的整个结构,需要感动吗?

那么这是指针的一个论据吗?或者向量内部只是指向分配的内存的指针?对于列表等也会有同样的问题...

关于重定向的成本与复制小对象的成本是否有任何经验法则?也许沿着 5 指针重定向 = 1 整数复制的思路?

谢谢

A similar question has been asked here:

Class members that are objects - Pointers or not? C++

so I'll keep it brief.

Say I have an object that contains three stl vectors. Is my thinking correct that if they are regular members of the class, the memory of them will be "together" for the whole object? e.g. my memory would look sth like 10 blocks vector A, 5 blocks vector B, and then 15 blocks vector C. Would then once I insert more objects into vector A so that the space runs out the whole structure including vector B and C need to be moved?

Is that then an argument for pointers? Or are vectors internally only a pointer to the allocated memory? Same question would go for lists etc...

Are there any rules of thumb as to the cost of a redirection vs the cost of copying small objects? Maybe sth along the lines of 5 pointer redirection = 1 integer copy?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南城旧梦 2024-11-12 15:33:24

假设我有一个包含三个 stl 向量的对象。我的想法是否正确,如果他们是班级的正式成员,他们的记忆将是整个对象的“在一起”?例如,我的记忆看起来像 10 个块向量 A、5 个块向量 B,然后是 15 个块向量 C。

每个向量在包含对象中占据固定大小,与当前存储的元素数量无关通过向量vectorvalue_type 可能(例如 vector 具有 value_type int< /code>) 不会影响所包含的 vector 对象本身的大小:仅影响 vector 维持其存储容量所需的堆分配存储量(所以他们很可能是 8 或每个 16 或 32 字节,但都相同,但不是 10 个“块”(无论是什么)、5 个块和 15 个“块”。

一旦我向向量 A 中插入更多对象,以致空间耗尽,是否需要移动包括向量 B 和 C 在内的整个结构?

将元素插入 A 只能导致 A 中的现有元素被移动(当超出容量时)。 BC 永远不会受到影响。

这就是指针的参数吗?或者向量内部只是指向已分配内存的指针?

是的,这是一个参数......这样一个好参数,是的,向量已经确实使用指向连续内存的指针,其中实际的value_type元素被存储。

对于列表等也会有同样的问题......

是的,列表也将它们的value_type元素存储在堆上,以及嵌入或从派生的对象的大小list 不受 list 上的操作影响。

关于重定向的成本与复制小对象的成本是否有任何经验法则?也许类似于 5 指针重定向 = 1 整数复制?在此处输入代码

C++ 运行在太多平台上,因此没有良好的经验法则。即使在 x86 处理器上,指令集、核心数量、缓存大小、CPU 供应商/型号/代等方面的差异也可能是巨大的。如果间接导致内存页面错误,那么它的成本是最高的,并且这非常依赖于机器上程序执行的整体情况。如果您愿意,请对运行该程序的真实计算机进行基准测试,直到找到统计相关且稳定的结果。

Say I have an object that contains three stl vectors. Is my thinking correct that if they are regular members of the class, the memory of them will be "together" for the whole object? e.g. my memory would look sth like 10 blocks vector A, 5 blocks vector B, and then 15 blocks vector C.

Each vector occupies a fixed size in the containing object, independent of the number of elements currently stored by the vector. It is likely that the value_type of the vector (e.g. vector<int> has value_type int) won't affect the size of the contained vector object itself: only the amount of heap-allocated store the vector needs in order to maintain its storage capacity (so they're likey to be say 8 or 16 or 32 bytes each but all the same, but not 10 "blocks" (whatever that might be), 5 blocks and 15).

Would then once I insert more objects into vector A so that the space runs out the whole structure including vector B and C need to be moved?

Inserting elements into A can only ever cause existing elements in A to be moved (when the capacity is exceeded). B and C can never be affected.

Is that then an argument for pointers? Or are vectors internally only a pointer to the allocated memory?

YES, it's an argument... such a good one that YES, vectors already do use pointers to the contiguous memory where the actual value_type elements are stored.

Same question would go for lists etc...

YES, lists store their value_type elements on the heap too, and the size of the object embedding or derived from list is unaffected by operations on the list.

Are there any rules of thumb as to the cost of a redirection vs the cost of copying small objects? Maybe sth along the lines of 5 pointer redirection = 1 integer copy?enter code here

C++ runs on too many platforms for there to be good rules of thumb for this. Even on say x86 processors, differences in instruction set, # cores, cache sizes, CPU vendor / model / generation etc. can be overwhelming. Indirection is most costly if it results in memory page faults, and that's very dependent on the overall picture of program execution on the machine. If you care, benchmark real computers running the program until you find statistically relevant and stable results.

ˉ厌 2024-11-12 15:33:24

集合类在内部使用指针实现 - 您不必担心它们耗尽空间。至于复制开销,不必担心,除非您通过分析代码证明这是一个问题。

Collection classes are implemented internally using pointers - you don't have to worry about them running out of space. As for the copying overhead, don't worry about it unless you have proved by profiling your code that it is a problem.

说谎友 2024-11-12 15:33:24

由于 std::vector 的大小是动态调整的,因此它们不可能将其元素存储为成员或成员数组。请记住,对象的大小在编译时是已知的。

即使如此,关于不使用指针成员仍然有一些话要说。考虑这种类型:

struct fat {
    array<double, 30> data;
    array<long, 30> more_data;
    array<char, 30> too_much_data;
};

其中 array 可以是 std::arraystd::tr1::arrayboost::array< /代码>;它在这里只是用作大型类型的替代品。你是对的,fat 对象将会很大。将成员更改为指针(或动态数组或任何类型的道德等价物)仍然为时过早:首先按原样使用对象,然后如果它太大或有其他问题,您可以动态分配它们成员的:

fat* so_much_stuff = new fat[30]();
// Better:
std::vector<fat> get_rid_of_it_already(30);

值语义只是让事情变得更容易;只有在复制或大小或其他任何东西(首先测量)但不是之前时,您才应该使用(动态)容器和智能指针(它们本身遵循值语义)。

编辑

std::vector 一般来说(无论是否是会员)都不是“坏”,请参阅评论中与托尼的讨论。

Since std::vector are dynamically sized, they can't possibly stores their elements as members or as a member array. Remember that the size of an object is known at compile-time.

Even then, there is still something to be said about not using pointer members. Consider this type:

struct fat {
    array<double, 30> data;
    array<long, 30> more_data;
    array<char, 30> too_much_data;
};

where array can be std::array, std::tr1::array or boost::array; it's here just used as a stand-in for a large type. You are correct that fat objects will be, well, large. Changing the members to pointers (or dynamic arrays or any kind of moral equivalent) is still premature: first use the objects as-is, and then if it's too big or otherwise problematic you can dynamically allocate them instead of the members:

fat* so_much_stuff = new fat[30]();
// Better:
std::vector<fat> get_rid_of_it_already(30);

Value semantics just make things easier; it's only until it's too much copying or size or whatever (measure first) but not before that you should use (dynamic) containers and smart pointers (that themselves follow value semantics).

EDIT

std::vector is not 'bad' in general (as a member or not), see the discussion with Tony in the comments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文