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
     
JHaackAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.