用成员函数初始化数据成员



我今天学习了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.
};

这会引起问题吗?

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

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

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

用于成员初始化的大括号或等号初始化式在标准9.2节中定义。第4点说"大括号或等号初始化式只能出现在数据成员的声明中。"

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

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

本节第13点说:"可以为正在构造的对象调用成员函数(包括虚成员函数)。"…但是,如果这些操作是在变量初始化器(或直接调用的函数)中执行的在基类的所有初始化器都完成之前,操作的结果是未定义的。"。最后一个例外不应该发生在您的情况中。

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

编辑: 根据12.6.2 pt.8,大括号或等号初始化器仅在对象的构造函数没有成员的mem初始化器(即使用":"语法的初始化器)

时使用。

最新更新