The problem is not that the pointers waste space. The problem is that they introduce irregular memory layout. If you want to, say, offload your data to a GPU, then having a structure memory layout is a huge benefit. But you'll kill performance if you have to chase pointers to first get the data in a format the GPU can handle. Other optimizations - such as SIMD on conventional processors - can apply.
And, for the record, C++ would not use pointers. In C++, if you place one object inside the definition of another, the whole object will be there, not a pointer. You control memory layout in C++. And if your objects are plain old data (POD), then it behaves just as C does. A C++ class that does not have any virtual members is laid out like a struct.
>The problem is that they introduce irregular memory layout.
Good point. I thought that the original thread was about pointers eating up space.
My understanding is that C++ class definitions, because they themselves may contain function references...even just constructors/destructors and access methods, would represent the object with a pointer on the call stack to the location of the object (and all its data + method pointers) on the heap (which like you said could end up anywhere resulting in an irregular memory layout). Otherwise, suppose a class is defined as a collection of objects (which are defined as collections of objects on down etc.) some of which may of arbitrary length...ergo you'd never know how much memory to allocate a priori to hold these irregular data structured. Far easier to just allocate a bunch of word length pointers pointing to whatever random blobs of address space the OS gives back on malloc requests.
But yeah, if it's just POD then one would assume an easy optimization the compiler could make would be to just create the objects as contiguous blocks of object-sized memory. I'm all rusty on some of this stuff (last time I seriously used C++ Borland was still a major player in the compiler business and templates were highly experimental) so I'm sure I'm quite out of date these days.
To be fair, wasted space was a point many people were making. But it's not the only consideration to make.
Anyway, most C++ compilers will turn the following:
obj.method(arg);
Into:
method(&obj, arg);
Conceptually, if not literally. One of the design principles of C++, as stated by Stroustrup, is that you don't pay for what you don't use. So if your classes have no virtual functions and are not a part of an inheritance hierarchy, they should be just plain ol' data. C++ compilers will generate different implementations for different kinds of classes. When virtual members are involved, a C++ object is usually more than just plain ol' data.
But, even in such objects, consider:
class Circle: public Shape {
virtual void draw();
Point coords;
};
In this case, a Circle object will probably not be just POD because it will need to resolve draw() at runtime. But, a Point object will live somewhere in a Circle object - not just a pointer to a Point object. If you wanted that, then you would say:
class Circle: public Shape {
virtual void draw();
Point* coords;
};
And, of course, you would be responsible for managing the dynamic memory for the coords member.
And, for the record, C++ would not use pointers. In C++, if you place one object inside the definition of another, the whole object will be there, not a pointer. You control memory layout in C++. And if your objects are plain old data (POD), then it behaves just as C does. A C++ class that does not have any virtual members is laid out like a struct.