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
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, vector
s already do use pointers to the contiguous memory where the actual value_type
elements are stored.
Same question would go for lists etc...
YES, list
s 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.
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.
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.
精彩评论