Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 320
  • Last Modified:

Looking for a polymorphic SizeOf operator

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
JHaack
Asked:
JHaack
1 Solution
 
JHaackAuthor Commented:
Edited text of question
0
 
Tommy HuiEngineerCommented:
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
 
JHaackAuthor Commented:
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
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
nietodCommented:
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
 
JHaackAuthor Commented:
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
 
LucHoltkampCommented:
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
 
nietodCommented:
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
 
JHaackAuthor Commented:
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
 
JHaackAuthor Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now