tags:

views:

67

answers:

4

Hi,
is it possible to return the sizeof a derived class already from base class/struct?

imho the size of a class is a kind of property of itself, like the weight of a human being. But I don't want to write the same function in every class.

many thanks in advance
Oops PS: so code to make my question more clear:

template <typename T>
struct StructBase {
    size_t size<T>(){
        return sizeof(T);
    }
};

struct MyStruct: public StructBase<MyStruct> {
    double d1;
    double d2;
    double d3;
    MyStruct(): d1(0), d2(0), d3(0){}
    //I do not want to do this here
    //size_t size(){ //return size<MyStruct> ;}
};

int main(void) {
   MyStruct m;
   std::cout << m.size(); //nop ?!?
}
+1  A: 

You can't overload the sizeof operator. And I'm not sure what you are asking:

class A {
   int x, y;
};

then:

size_t n = sizeof( A );

gives you the size of class A - I don't see where derivation comes into this.

Edit: and regarding your expanded question, I don't see why you can't say:

MyStruct m;
std::cout << sizeof( m );

Note that size is not a property like weight - weight can change, and is different for different instances. The size of a class must be known by the compiler at compile time and cannot ever change.

anon
+1  A: 
class A {
  int a;
}

class B : A {
 int b;
}

The size of B (2xint) is twice the size of A (1xint), sizeof does NOT refer to an object but to a type. I know what you want to do, but polymorphism only works with objects, not types. So if you do sizeof(A) and expect it to return the size of B, think twice, the processor has no way to know that you wanted the size of B instead of A, since they are differents ;-)

Aurélien Ribon
"The size of B (2xint) is twice the size of A (1xint)" - unless padding messes up the nice picture :-(
Péter Török
+2  A: 

Since base classes are not supposed to know about classes derived from them (that would create a circular dependency), a base class method can't even know what extra fields have been added to a derived class. Moreover, sizeof can't be polymorphic - it only works on static types and structures. Hence there is no point trying something like sizeof(*this).

So it's not going to work.

Update: well, now it is a completely different question. With templates this may even work FWIW (I don't have an IDE to try it out). But notice that now you practically have a template function with a type parameter which can be anything - restricted to derived classes only by you, the programmer. And overall, I don't see what you actually win with this solution - which may be due to lack of context as well.

Péter Török
A: 

Here is an example of how this could be done:

template <typename T> 
struct StructBase { 
    unsigned int const size;
    StructBase<T>():size(sizeof(T)) { }
}; 

struct MyStruct: public StructBase<MyStruct> { 
    double d1; 
    double d2; 
    double d3; 
    MyStruct(): d1(0), d2(0), d3(0){} 
    //I do not want to do this here 
    //size_t size(){ //return size<MyStruct> ;} 
};

indeed it is very easy, but there is one drawback: the size of every struct that's derived from structBase will have one more variable, and depending on the other variables the size could be increased significantly:
in this example the size of MyStruct is 24 bytes without the baseclass StructBase but with the baseclass it is 32 bytes. that's something what you maybe do not like to have in every case.

regards Oops

Oops
The syntax in the first template will not compile. "StructBase<T>():size(sizeof(T)) { }" makes no sense.
Joseph Garvin
but YES, it compiles (VS2010). what compiler do you use?
Oops