有条件地初始化C成员变量的正确方法?

我相信这是一个非常简单的问题.以下代码显示了我要做的事情:
class MemberClass {
public:
    MemberClass(int abc){ }
};

class MyClass {
public:
    MemberClass m_class;
    MyClass(int xyz) {
        if(xyz == 42)
            m_class = MemberClass(12);
        else
            m_class = MemberClass(32);
    }
};

这不会编译,因为m_class正在使用一个空构造函数(不存在)来创建.这样做的正确方法是什么?我的猜测是使用指针和实例化m_class使用新的,但我希望有一个更简单的方法.

编辑:我应该早点说过,但我的实际问题有一个额外的复杂性:我需要调用一个方法,然后初始化m_class,以便设置环境.所以:

class MyClass {
public:
    MemberClass m_class;
    MyClass(int xyz) {
        do_something(); // this must happen before m_class is created
        if(xyz == 42)
            m_class = MemberClass(12);
        else
            m_class = MemberClass(32);
    }
};

有可能通过花哨的初始化列表技巧来实现这一点吗?

解决方法

使用条件运算符.如果表达式较大,请使用函数
class MyClass {
public:
    MemberClass m_class;
    MyClass(int xyz) : m_class(xyz == 42 ? 12 : 32) {

    }
};

class MyClass {
    static int classInit(int n) { ... }
public:
    MemberClass m_class;
    MyClass(int xyz) : m_class(classInit(xyz)) {

    }
};

要在初始化m_class之前调用函数,可以在该成员之前放置一个结构体并利用RAII

class MyClass {
    static int classInit(int n) { ... }
    struct Environmentinitializer {
        Environmentinitializer() {
            do_something();
        }
    } env_initializer;
public:
    MemberClass m_class;
    MyClass(int xyz) : m_class(classInit(xyz)) {

    }
};

这将在初始化m_class之前调用do_something().请注意,在构造函数初始化程序列表完成之前,不允许调用MyClass的非静态成员函数.该函数必须是其基类的成员,并且基类“ctor”必须已经完成才能使其工作.

还要注意的是,对于每个单独的对象,这个函数当然总是被调用,而不仅仅是创建的第一个对象.如果要这样做,可以在初始化程序的构造函数中创建一个静态变量:

class MyClass {
    static int classInit(int n) { ... }
    struct Environmentinitializer {
        Environmentinitializer() {
            static int only_once = (do_something(),0);
        }
    } env_initializer;
public:
    MemberClass m_class;
    MyClass(int xyz) : m_class(classInit(xyz)) {

    }
};

它使用逗号运算符.请注意,您可以使用function-try块捕获do_something抛出的任何异常

class MyClass {
    static int classInit(int n) { ... }
    struct Environmentinitializer {
        Environmentinitializer() {
            static int only_once = (do_something(),0);
        }
    } env_initializer;
public:
    MemberClass m_class;
    MyClass(int xyz) try : m_class(classInit(xyz)) {

    } catch(...) { /* handle exception */ }
};

do_something函数将被下次再次调用,如果它抛出引起MyClass对象失败的异常.希望这可以帮助 :)

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...