Solved

Looking for a polymorphic SizeOf operator

Posted on 1997-12-08
9
304 Views
Last Modified: 2008-03-17
I am trying to determine the size of a derived class given a base class pointer.  As you know, when I call a virtual function with the base class pointer I will, through polymorphism, get the derived execution.  However, if I dereference the base-class pointer and ask for the size of the object using SizeOf, I get the size of the base class. For instance, the example below yields:

Size of *pBase = 88
Size of *pDerived = 248

#include <stdio.h>

class Base
{
public:
      Base() {}
      virtual ~Base() {}

protected:
      double m_BaseDouble[10];
};

class Derived : public Base
{
public:
      Derived() {}
      virtual ~Derived() {}

protected:
      double m_DerivedDouble[20];
};

int
main()
{
      Derived* pDerivedBase = new Derived;
      Base* pBase = pDerivedBase;
      Derived* pDerived = new Derived;

      int baseSize = sizeof(*pBase);
      printf("Size of *pBase = %d\n", baseSize);

      int derivedSize = sizeof(*pDerived);
      printf("Size of *pDerived = %d\n", derivedSize);

      return 0;
}

How can I get the size of the derived class (object) without having to overload the SizeOf operator?  How can I dynamically "upcast" to the derived class without actually knowing the derived class?  I want the results to yield

Size of *pBase = 248
Size of *pDerived = 248
     
0
Comment
Question by:JHaack
9 Comments
 

Author Comment

by:JHaack
ID: 1175206
Edited text of question
0
 
LVL 15

Expert Comment

by:Tommy Hui
ID: 1175207
If you have access to the base and derived class, then it would be easier to add a virtual function that returns the size of the class.
0
 

Author Comment

by:JHaack
ID: 1175208
Let me reiterate.  I do not want to have to overload the SizeOf operator - or any other operator/function.  Your proposal simply provides a SizeOf operator with a different name.  I would still have to overload the size retrieval function in each derived class.  What I really need is a way of using the base-class pointer polymorphically to determine the size of the derived object.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1175209
I have to agree with thui.  You want polymorphic behavior.  Virtual functions are what provide polymorphic behavior.  Just add a virtual function to each class called GetSizeOf(), for example.  You should be able to use templates to create the function for each class (base and derived).
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:JHaack
ID: 1175210
I don't disagree with either thui or nietoid, but I'm aware of the possibility of adding a virtual function and, let me state it again - that is not the answer to my question.  I want a global way of determining the size of a derived object given a pointer to it's base class (say CObject).  Adding a virtual function adds overhead to my current classes and every future class that I develop and it requires me to rewrite all third party classes that I am currently using - ultimately opening up the door for some errors.  Again, I do not want an answer that involves a virtual function.  I want an answer that takes the base-class pointer and uses it to determine the type of the derived class.
0
 
LVL 3

Accepted Solution

by:
LucHoltkamp earned 150 total points
ID: 1175211
The best solution is to add a virtual to the baseclass and derived classes:
virtual size_t SizeOf() { return sizeof(*this); }

If you don't want to do this you can write a function that checks for the type. The disadvantage is that you have to know the classhierarchy.

class A {int a; };
class B : public A {int b; };
class C : public B {int c; };

long SizeOf(A *aPtr)
{
  if (typeid(*aPtr) == typeid(A)) return sizeof(A);
  else if (typeid(*aPtr) == typeid(B)) return sizeof(B);
  else if (typeid(*aPtr) == typeid(C)) return sizeof(C);
  else return -1; // Unknown class,
}

or dynamically:

Create a static container containing objects that combine the name of a class and its size. When you need the size of an object you could look it up by its name, using typeid. Adding classes to the container could be done with a macro that inserts the data in the container.

/* Header file (sizeof.hpp) */

#include <stddef.h>
#include <typeinfo.h>

// adds an entry to the container. The returned (dummy)int is
// used to initialize the dummy static. This trick is to get code
// running without using startup pragma's
int register_sizeof(const char* class_name, size_t sizeof_class);

// retrieve the size of a class by looking it up in the container.
size_t size_of(const char* class_name);

// add this macro for each class you want to get the size of in a code file, ie
// REGISTER_SIZE(MyClass);
#define REGISTER_SIZE(a)  \
  static int dummy_##a = register_sizeof(typeid(a).name(), sizeof(a))

// you call this function if you want to know the size of some object
//
template<class T>
inline size_t SizeOf(T&)
{
  return size_of(typeid(T).name());
}

/* End of Header */

/* Code File (sizeof.cpp) */



#include <utility>
#include <map>
#include "sizeof.hpp"

static map<string, size_t> sizes;

int register_sizeof(const char* class_name, size_t its_size)
{
  sizes.insert(pair<string, size_t>(string(class_name), its_size));
  return 0;
}

size_t size_of(const char* class_name)
{
  return sizes.find(string(class_name));
}

/* End of Code file */

.luc.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1175212
I can see your delema.  (I'm not sure I can spell it, but I can see it).  Unfortunately, I don't think there is a solution.  If there is, its going to have to involve templates.  But I don't see a way without templates and virtual functions.  

Perhaps there is a different angle, though.  What are you trying to do that you need this?  
0
 

Author Comment

by:JHaack
ID: 1175213
I'm using it to include memory tracking throughout my application.  Specifically, two functions - Allocate and Deallocate - will be used in place of new and delete (or malloc and free) and will track the amount and blocks of memory allocated and deallocated..  Generally,

Deallocate(Base* p)
{
  bytes -= sizeof(*p);
  delete p;
}


0
 

Author Comment

by:JHaack
ID: 1175214
I would have given you an A, but your solution requires some overhead in "registering" the classes.  However, your suggestion is probably the best, or at least as good as any.  It would be nice if the ANSI standard was revised to require that new and delete (malloc and free) return the amount of memory which was allocated or released.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

919 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now