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

时间:2014-08-08 19:15:05

标签: c++ memory-management initialization data-members

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

这会导致问题吗?

2 个答案:

答案 0 :(得分:1)

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

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

此处ab之前初始化,但{undeder}值为b。 静态成员函数应该没问题。

答案 1 :(得分:0)

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

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

这意味着在调用数据成员brace-or-equal-initializer时,始终会初始化基类(类的类)。

该部分的第13点说: "可以为正在构建的对象调用成员函数(包括虚拟成员函数)。" 。 .."但是,如果这些操作是在ctor-initializer(或直接调用的函数)中执行的 或者在基类的所有mem-initializer完成之前,间接来自ctor-initializer),操作的结果是不确定的。 &#34 ;.在您的情况下不应该发生最后一个异常。

是的,这种陈述应该是有效的。

<强> 编辑: 根据12.6.2 pt.8,只有当对象的构造函数没有成员的mem-initializer时才使用括号或等于initaliszer(即初始化器为&#34;:&#34;语法)