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

前端之家收集整理的这篇文章主要介绍了有条件地初始化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对象失败的异常.希望这可以帮助 :)

原文链接:https://www.f2er.com/c/114134.html

猜你在找的C&C++相关文章