Позволит ли целевой конструктор C ++ 11 мне безопасно инициализировать производный класс из конструктора шаблона? - PullRequest
0 голосов
/ 06 мая 2019

У меня есть множество объектов, созданных из панели шаблонов классов (ниже). Каждый объект имеет элемент данных с различным типом данных (например, std :: string, bool, int и т. Д.)

У меня есть набор текущих значений по умолчанию каждого из производных / шаблонных типов в статическом массиве, который был создан с помощью new.

Я бы хотел инициализировать объект в конструкторе, БЕЗ отдельного шага инициализации.

Я могу быть уверен, что тип объекта по умолчанию, который я извлекаю из статического массива, абсолютно ТАКОЙ ЖЕ шаблонный тип.

Я полагаю, что сталкиваюсь с проблемой, что панель объектов на самом деле не является панелью объектов типа, пока конструктор не завершит работу? Разве в C ++ 11 нет способа использовать целевые или делегированные конструкторы, чтобы обойти это?

class foo
{
public:
    foo(int index) : fMyIndex(index) { }

protected:
    int fMyIndex;

};

template<class T>
class bar : public foo
{
public:
    // This constructor takes the integer prefIndex, then constructs
    // the object based on current in-memory settings, which it obtains from a static array via static GetDefaultData;
    //
    bar(int index) : foo(index)
    {
        // get the most current version of the in-memory data.  defaultObject is a pointer to a "BarString"
        foo* defaultObject = static_cast<bar*>(GetDefaultData(fMyIndex));
        if (defaultObject) {
            // bad memory access!
            *this = *defaultObject;
        }
    }

private:
    T fMyData;

};


typedef bar<std::string> BarString;
typedef bar<int> BarInt;
typedef bar<bool> BarBool;

1 Ответ

1 голос
/ 06 мая 2019

Конечно, вы можете использовать делегированный конструктор, но мне интересно, почему вы получаете плохой доступ к памяти:

// bad memory access!
*this = *defaultObject;

Насколько я знаю, в этом нет ничего плохого.


Но на самом деле вы можете использовать делегированные конструкторы, если вы не вызываете базовый конструктор напрямую, как вы это делаете. Вместо этого конструктор копирования bar вызовет соответствующий конструктор для своей базы.

template<class T>
struct bar : foo {
    // This constructor takes the integer prefIndex, then constructs
    // the object based on current in-memory settings, which it obtains from a static array via static GetDefaultData;
    bar(int index) : bar(*static_cast<bar*>(GetDefaultData(index))) {}

private:
    T fMyData;
};
...