3

我今天学习了 C++ 11 非常有用的新特性,它允许在类声明中直接初始化数据成员:

class file_name
{
    public:
    file_name(const char *input_file_name);
    ~file_name();

    private:
    char *file_name=nullptr;  //data_member is initialized to nullptr;
    char *Allocator(int buffer_size);  //code to dynamically allocate requested
                                       //size block of memory.
};

是否可以使用新的 v11 规则更进一步,并使用成员函数的输出初始化数据成员:

class file_name
{
    public:
    file_name(const char *input_file_name);
    ~file_name();

    private:
    char *file_name=Allocator(MAX_PATH);  //data_member is initialized with a block of
                                          //dynamic memory of sufficient size to hold
                                          //and valid file name.;
    char *Allocator(int buffer_size);  //code to dynamically allocate requested
                                       //size block of memory.
};

这会导致问题吗?

4

2 回答 2

1

非静态成员函数(通常)以某种方式取决于调用它的对象的状态。如果不是这种情况,就没有理由将其设为非静态成员函数。现在,您想在完全构造对象之前调用一个依赖于对象状态的 函数,即该函数可能依赖的不变量尚未建立。因此,使用这样的函数具有潜在的危险,因为例如该函数可能会访问未初始化的变量。考虑这个例子:

class Fail {
    int a = fun() , b;
    int fun() {return b;}
};

这里a在 之前被初始化b,但使用 的(未定义)值b。静态成员函数应该没问题。

于 2014-08-08T19:52:30.797 回答
0

您用于成员初始化的大括号或相等初始化器在标准中定义,在第 9.2 节中。第 4 点说“大括号或等号初始化器应仅出现在数据成员的声明中。”

构造过程中成员的初始化在第 12.6.2 节中描述。
第 10 点描述了顺序:1)大多数派生基类,2)直接基类初始化器,3)非静态数据成员 4)构造函数的复合语句。

这意味着当你的数据成员括号或相等初始化器被调用时,基类(你的类)总是被初始化。

该部分的第 13 点说:“可以为正在构建的对象调用成员函数(包括虚拟成员函数)。” ...“但是,如果在基类的所有 mem-initializers 完成之前,在 ctor-initializer 中(或在从 ctor-initializer 直接或间接调用的函数中)执行这些操作,则操作的结果是未定义的.". 最后一个例外不应该发生在您的情况下。

所以是的,这种说法应该是有效的。

编辑: 根据 12.6.2 pt.8,仅当对象的构造函数没有成员的 mem-initializer(即具有“:”语法的初始化器)时才使用大括号或相等初始化器

于 2014-08-08T19:58:25.750 回答