2016-05-17 6 views
4

Рассмотрим следующий пример, когда срез объекта происходит во время разыменования базового указателя.Есть ли механизм в C++ для создания полной копии производного класса из указателя базового класса без выделения динамической памяти?

#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(); 
} 

Я хочу переменную d для хранения объекта типа Derived вместо объекта типа Base без динамического выделения памяти, и без явного приведения.

Я уже рассмотрел this question, но для решения, предлагаемого в ответ, требуется динамическое выделение памяти, поскольку оно возвращает указатель на новый объект вместо значения нового объекта.

Возможно ли это в C++ 11?

+0

Можете ли вы ограничить свою иерархию классов каким-то образом? Если существует ограниченное количество типов, вы можете пойти с 'boost :: variant'. Если вы можете ограничить максимально возможный размер объекта разумным значением, вы можете создать класс интеллектуальных указателей, чтобы управлять им. – milleniumbug

+0

@milleniumbug. На практике производный класс является шаблоном, поэтому я не думаю, что могу его связать. – merlin2011

ответ

6

Нет, это невозможно, поскольку если d не имеет динамической продолжительности хранения, то он должен иметь статическую, поточную или автоматическую продолжительность хранения, и во всех этих случаях тип объекта известен при компиляции время. В вашем случае вы хотите, чтобы тип объекта определялся во время выполнения, так как ptrToDerived может указывать на объект Base или объект Derived или на объект какого-либо другого класса, производный от Base.

Если ваша проблема связана с потерей жизни и утечкой памяти, просто введите clone, а не , а не Base*.

+0

Это несчастливо. Я избегаю динамического распределения памяти по причинам производительности. – merlin2011

+0

@ merlin2011: Посмотрите на вариант (например, 'boost :: variant'), который может хранить один из многих ваших производных классов в блоке памяти. Это заставляет вас статически знать, какие производные классы вы, возможно, захотите, конечно. – GManNickG

3

Я думаю, вы имеете в виду, что хотите auto вывести на D.

Однако это невозможно: все типы должны быть известны во время компиляции. Представьте себе, если код был:

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

Там нет никакого способа, компилятор может знать динамический тип, что указывает на b, потому что он не может быть решен до момента выполнения.