Подтвердить что ты не робот

Есть ли простой способ инициализировать простой класс без конструктора?

У меня очень простой класс, например:

class MySimpleClass
{
public:
    uint16_t   m_myInt;
    String     m_myString;
    String     m_myOtherString;
    MyEnum     m_myEnumValue;
    bool       m_myBool;
};

Этот класс является частью предварительно скомпилированной библиотеки, которую я не могу изменить, и она не предлагает конструктор. Есть ли способ, которым я могу инициализировать этот класс без необходимости делать что-то вроде этого...

MySimpleClass msc;
msc.m_myInt = 1;
msc.m_myString = "foo";
msc.m_myOtherString = "bar";
msc.m_myEnumValue = ENUM_VALUE_YES;
msc.m_myBool = true;

Я не прочь сделать это таким образом, но мне любопытно узнать, есть ли какой-то синтаксис инициализации, который это сделает?

Я работаю на С++ 03, но ответы на С++ 11 также будут интересны.

4b9b3361

Ответ 1

Вы можете добавить бесплатную функцию, которую вы можете использовать в качестве конструктора:

MySimpleClass make_msc(
    uint16_t myInt,
    String myString,
    String myOtherString,
    MyEnum myEnumValue,
    bool myBool)
{
    MySimpleClass msc;
    msc.m_myInt = myInt;
    msc.m_myString = myString;
    msc.m_myOtherString = myOtherString;
    msc.m_myEnumValue = myEnumValue;
    msc.m_myBool = myBool;
    return msc;
}

//Usage:
MySimpleClass msc = make_msc(1,"foo","bar",ENUM_VALUE_YES,true);

В качестве альтернативы вы можете использовать агрегатную инициализацию:

MySimpleClass msc = {1,"foo","bar",ENUM_VALUE_YES,true};//C++03 or C++11
MySimpleClass msc{1,"foo","bar",ENUM_VALUE_YES,true}; //C++11 only

Примечание.

MySimpleClass msc = {1,"foo","bar",ENUM_VALUE_YES,true};
Форма

может использоваться только в объявлении, но:

MySimpleClass{1,"foo","bar",ENUM_VALUE_YES,true}
make_msc(1,"foo","bar",ENUM_VALUE_YES,true)

формы могут использоваться в любом выражении, которое ожидает MySimpleClass.

Ответ 2

Равномерная инициализация в С++ 11 полезна

MySimpleClass x {1, "foo", "bar", NUM_VALUE_YES, true};

Ответ 3

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

Например:

class MyImprovedClass : public MySimpleClass
{
public:
    MyImprovedClass(uint16_t myInt, String myString, String myOtherString,
        MyEnum myEnumValue, bool myBool)
    {
        m_myInt = myInt;
        m_myString = myString;
        m_myOtherString = myOtherString;
        m_myEnumValue = myEnumValue;
        m_myBool = myBool;
    }
};

а затем используйте его, например:

MyImprovedClass msc(1, "Foo", "Bar", ENUM_VALUE_YES, true);

Насколько это касается MyImprovedClass, его можно передать как MySimpleClass и обработать то же самое. Другое преимущество здесь состоит в том, что вы можете принудительно инициализировать, сделав частный конструктор по умолчанию, например:

class MyImprovedClass : public MySimpleClass
{
public:
    MyImprovedClass(uint16_t myInt, String myString, String myOtherString,
        MyEnum myEnumValue, bool myBool)
    {
        // Implement as above...
    }

private:
    MyImprovedClass() {}
};

С другой стороны, если вы решите реализовать конструктор по умолчанию для "улучшенного" класса, вы можете автоматически инициализировать этот класс при динамическом распределении. Если вы выберете это, вы можете добавить конструктор копирования или даже расширить (и инкапсулировать) его функциональность, добавив больше функций-членов и сохранив порядок вещей.