4

Consider the following example, where object slicing occurs during dereference of a base pointer.

#include <stdio.h>

class Base {
  public:
    virtual void hello() {
        printf("hello world from base\n");
    }
};
class Derived : public Base{
  public:
    virtual void hello() {
        printf("hello world from derived\n");
    }
};

int main(){
    Base * ptrToDerived = new Derived;
    auto d = *ptrToDerived;
    d.hello();
}

I want the variable d to hold an object of type Derived instead of an object of type Base, without dynamic memory allocation, and without an explicit cast.

I have already looked at this question, but the solution proposed in the answer requires dynamic memory allocation, because it returns a pointer to the new object, instead of the value of the new object.

Is this possible in C++11?

Community
  • 1
  • 1
merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • Can you limit your class hierarchy in some way? If there's a bounded number of types, you could go with `boost::variant`. If you could limit the maximum possible size of an object to a reasonable value, you could create a smart pointer-like class to manage it. – milleniumbug May 17 '16 at 23:31
  • @milleniumbug, In practice the derived class is a templated class, so I don't think I can bound it. – merlin2011 May 18 '16 at 00:00

2 Answers2

6

No, it's not possible, because if d does not have dynamic storage duration, then it must have static, thread, or automatic storage duration, and in all of those cases, the type of the object is known at compile time. In your case, you want the type of the object to be determined at runtime, since ptrToDerived may point to a Base object or a Derived object or to an object of some other class derived from Base.

If your concern is about lifetime and memory leaks, just have clone return a std::unique_ptr<Base> instead of Base*.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • That's unfortunate. I am avoiding dynamic memory allocation for performance reasons. – merlin2011 May 17 '16 at 23:11
  • @merlin2011: Look into a variant (e.g., `boost::variant`) that can store one of many of your derived classes in a block of memory. This forces you to statically know which derived classes you might want, of course. – GManNickG May 17 '16 at 23:27
3

I guess you mean that you want auto to deduce to D.

However this is not possible: all types must be known at compile-time. Imagine if the code were:

Base *b = some_func();
auto d = *b;

There's no way the compiler can know the dynamic type of what b points to, because it might not be decided until runtime.

M.M
  • 138,810
  • 21
  • 208
  • 365