1

Suppose I have some simple classes/structs without anything but data and a select few operators. If I understand, a basic struct with only data in C++, just like C, occupies as much memory as the members. For example,

struct SomeStruct { float data; }
sizeof(SomeStruct) == sizeof(float); // this should evaluate to true

What I'm wondering is if adding operators to the class will make the object larger in memory. For example

struct SomeStruct
{
public:
    SomeStruct & operator=(const float f) { data = f; return this; }
private:
    float data;
}

will it still be true that sizeof(SomeStruct) == sizeof(float) evaluates to true? Are there any operators/methods which will not increase the size of the objects in memory?

xaviersjs
  • 1,579
  • 1
  • 15
  • 25

3 Answers3

3

The structure may not necessarily be only as large as its members (consider padding and alignment), but you are basically correct, in that:

Functions are not data, and are not "stored" inside the object type.

That said, watch out for the addition of virtual table pointers in the case where you add a virtual function to your type. This is a one-time size increase for the type, and does not re-apply when you add more virtual functions.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • What about virtual functions? – SirGuy Jan 18 '14 at 17:06
  • @GuyGreer: Well, okay, you have a vtable to consider in some implementations. But the functions themselves are never stored in the object. – Lightness Races in Orbit Jan 18 '14 at 17:16
  • Can you explain what you mean by padding and alignment? Is there any reason, for example `SomeStruct structArray[100]` would have a different size from `float floatArray[100]`? – xaviersjs Jan 21 '14 at 20:43
  • Well I don't have any books that talk about how the compiler allocated memory for c++ objects or arrays of objects. Do you have one in mind that does? Is it specified in the standard how object memory is packed? I've never taken a course that covered these topics (mostly because I don't have a degree in computer science) – xaviersjs Jan 22 '14 at 23:00
  • @xaviersjs: If your book doesn't teach the basics of alignment, padding and endianness, you need a new book! http://http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Lightness Races in Orbit Jan 23 '14 at 02:05
2

What I'm wondering is if adding operators to the class will make the object larger in memory.

The answer is "it depends".

If the class wasn't polymorphic prior to adding the function and this new function keeps the class non-polymorphic, then adding this non-polymorphic function does nothing to the size of your class instances.

On the other hand, if adding this new function does make your class polymorphic, this addition will make instances of your class bigger. Most C++ implementations use a virtual table, or vtable for short. Each instance of a polymorphic class contains a pointer to the vtable for that class. Instances of non-polymorphic classes don't need and thus don't contain a vtable pointer.

Finally, adding yet another virtual function to a class that is already polymorphic does not make the class instances bigger. This addition does makes the vtable for that class bigger, but the vtable itself isn't a part of the instance. A vtable pointer is a part of the instance, and that pointer is already a part of the class layout because the class is already polymorphic.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
1

When I was learning about C++ and OOP, I read somewhere (some bad source) that objects in C++ are essentially the same thing as C structs with function pointers inside of them. They may be like that functionally, but if they were really implemented like that, it would have been a huge waste of space since all object instances would have to store the same pointers.

Method code is stored in one central location and C++ just makes it conveniently look like as if each instance had its methods inside of it. (Operators are essentially functions with different syntax).

Methods and operators defined inside classes do not increase the size of instantiated objects. You can test it out for yourself:

#include <iostream>
using namespace std;

struct A {
  int a;
};
struct B {
  int a;
  //SOME RANDOM METHODS AND OPERATORS
  B() : a(1) {cout<<"I'm the constructor and I set 'a' to 1"<<endl;}
  void some_method() const { for(int i=0;i<40;i++) cout<<"loop";}
  B operator+=(const B& b){
    a+=b.a;
    return *this;
  }
  size_t my_size() const { return sizeof(*this);}


};

int main(){

cout<<sizeof(A)<<endl;
cout<<B().my_size()<<endl;

}

Output on a 64 bit system:

4
I'm the constructor and I set 'a' to 1
4

==> No change in size.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142