Suppose there is a hierarchy of two classes (class Derived: public Base). Both these classes have big memory footprint and costly constructors. Note that nothing in these classes is allocated in heap: they just have a big sizeof.
Then there is a function with a fast path (executed always) and a slow path (executed conditionally). Fast path needs a Base instance, and slow path needs a Derived instance constructed from existing base. Also, slow path decision can be made only after the fast path.
Current code looks like this:
void f()
{
    Base base;
    /* fast path */
    if (need_slow_path) {
        Derived derived (base);
        /* slow path */
    }
}
This is inefficient, because the base needs to be copied into derived; also the base is allocated twice and there is a risk of overflowing the stack. What I want to have:
Derived instanceBase ctor on itDerived ctor on the existing Base instance and execute the slow pathIs it possible in C++? If not, what are possible workarounds? Obviously, I'm trying to optimize for speed.
I am afraid this is not possible just as you wrote - any constructor of Derived must call a constructor of the Base subobject, so the only way to do that legally would be to call Base's destructor first, and I believe you don't want that.
However, it should be easy to solve this with a slight redesign - prefer composition over inheritance, and make Derived a separate class that will store a reference (in the general sense; it can of course be a pointer) to Base and use it. If access control is an issue, I feel a friend is justified here.
You should change your design slightly to change your reliance on inheritance to that on composition.
You could encapsulate members of derived class (not present in the base class) into another class, and keep it's null reference in the derived class.
Now directly initialize derived class without initializing new class's object.
Whenever slow path is required, you can initialize and use it.
Benefits
I can fake it.
Move/all the data of derived into an optional (be it boost or std::ts::optional proposal for post C++14, or hand rolled).
Iff you want the slow path, initialize the optional.  Otherwise, leave it as nullopt.
There will be a bool overhead, and checks when you assign/compare/destroy implicit.  And things like virtual functions will be derived (ie, you have to manage dynamic dispath manually).
struct Base {
  char random_data[1000];
  // virtual ~Base() {} // maybe, if you intend to pass it around
};
struct Derived:Base {
  struct Derived_Data {
    std::string non_trivial[1000];
  };
  boost::optional< Derived_Data > m_;
};
now we can create a Derived, and only after we m_.emplace() does the Derived_Data get constructed.  Everything still lives is in one contiguous memory block (with a bool injected by the optional to track if m_ was constructed).
Not sure if you can do exacactly what you want i.e execute "fast" path before second contructor but i think you use 'placement new' feature - manually call contructors based on need_slow_path predicate. i.e but that changes flow a little:
The example code
#include <memory> 
void f(bool need_slow_path)
{
    char bufx[sizeof(Derived)];
    char* buf = bufx;
    Derived* derived = 0;
    Base* base = 0;
    if (need_slow_path ) {
        derived = new(buf) Derived();
        base = derived;
    } else {
        base = new(buf) Base();
    }
    /* fast path using *base */
    if (need_slow_path) {
        /* slow path using *base & * derived */
    }
    // manually destroy
    if (need_slow_path ) {
        derived->~Derived();
    } else {
        base->~Base();
    }
}
Placement new is well described here: What uses are there for "placement new"?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With