有没有一种简单的方法来初始化一个没有构造函数的简单类?

Kar*_*oll 25 c++

我有一个非常简单的类,像这样:

class MySimpleClass
{
public:
    uint16_t   m_myInt;
    String     m_myString;
    String     m_myOtherString;
    MyEnum     m_myEnumValue;
    bool       m_myBool;
};
Run Code Online (Sandbox Code Playgroud)

这个类是我无法更改的预编译库的一部分,它不提供构造函数.有什么方法可以初始化这个类而不必做这样的事情......

MySimpleClass msc;
msc.m_myInt = 1;
msc.m_myString = "foo";
msc.m_myOtherString = "bar";
msc.m_myEnumValue = ENUM_VALUE_YES;
msc.m_myBool = true;
Run Code Online (Sandbox Code Playgroud)

我并不反对这样做,但我很想知道是否有某种初始化语法可以做到这一点?

我在C++ 03工作,但C++ 11中的答案也会引起人们的兴趣.

Man*_*rse 51

您可以添加一个可用作构造函数的自由函数:

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);
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用聚合初始化:

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
Run Code Online (Sandbox Code Playgroud)

注意:

MySimpleClass msc = {1,"foo","bar",ENUM_VALUE_YES,true};
Run Code Online (Sandbox Code Playgroud)

表单只能用于声明,但是:

MySimpleClass{1,"foo","bar",ENUM_VALUE_YES,true}
make_msc(1,"foo","bar",ENUM_VALUE_YES,true)
Run Code Online (Sandbox Code Playgroud)

表单可用于任何需要a的表达式MySimpleClass.

  • +1对于免费功能解决方案:如果库供应商决定改变其结构布局,那么唯一的远程可靠解决方案. (9认同)
  • @KarlNicoll:要么以不正确的顺序静默初始化结构,要么会出现编译错误. (3认同)

mas*_*oud 14

C++ 11中的统一初始化很有用

MySimpleClass x {1, "foo", "bar", NUM_VALUE_YES, true};
Run Code Online (Sandbox Code Playgroud)


Eit*_*n T 9

在游戏中稍晚,但我认为更优雅的方法是创建一个继承自类的子类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;
    }
};
Run Code Online (Sandbox Code Playgroud)

然后使用它,例如:

MyImprovedClass msc(1, "Foo", "Bar", ENUM_VALUE_YES, true);
Run Code Online (Sandbox Code Playgroud)

MyImprovedClass问题而言,它可以被传递MySimpleClass和处理相同.这里的另一个好处是你可以通过将默认构造函数设为私有来强制初始化,例如:

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

private:
    MyImprovedClass() {}
};
Run Code Online (Sandbox Code Playgroud)

另一方面,如果您选择为"改进"类实现默认构造函数,则可以在动态分配期间自动初始化此类.如果您选择这样,您可以添加复制构造函数,甚至通过添加更多成员函数来扩展(并封装)其功能,并保持整洁.

  • 如果析构函数需要是虚拟的并且未在基类中声明,则可能导致内存泄漏. (2认同)