简体   繁体   English

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

[英]Initializing Data Members with a Member Function

I have today learned the very useful new feature of C++ 11 which allows direct initialization of data members in the class declaration: 我今天学到了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.
};

Is it possible to take this a step further with the new v11 rules and initialize a data member with the output of a member function: 是否可以使用新的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.
};

Would this cause problems? 这会引起问题吗?

A non-static member function (usually) somehow depends on the state of the object it is called in. If this would not be the case, there would not really be a reason to make it a non-static member function. 非静态成员函数(通常)以某种方式取决于它所调用的对象的状态。如果不是这种情况,则实际上没有理由使其成为非静态成员函数。 Now you want to call a function that depends on the state of your object before said object is completely constructed, ie its invariants the function might rely on are not necessarily established yet. 现在,您希望在完全构造所述对象之前调用依赖于对象状态的函数,即函数可能依赖的不变量尚未建立。 So using such a function is potentially dangerous since eg the function might access uninitialized variables. 因此,使用这样的函数是有潜在危险的,因为例如函数可能访问未初始化的变量。 Consider this example: 考虑这个例子:

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

Here a gets initialized before b , but with the (undefined) value of b . 这里a被初始化之前b ,但随着(未定义)值b A static member function should be fine though. 静态成员函数应该没问题。

The brace-or-equal-initializer that you use for member initialisation is defined in the standard, in section 9.2. 用于成员初始化的括号或等于初始化程序在标准9.2中定义。 Point 4 says "A brace-or-equal-initializer shall appear only in the declaration of a data member." 第4点说“支持或等于初始化程序只应出现在数据成员的声明中。”

The initialisation of members in the construction process are sescribed in section 12.6.2. 施工过程中成员的初始化见第12.6.2节。
Point 10 describes the order: 1) most derived base class, 2) direct base class initialiser, 3) non static data members 4) compound statement of the constructor. 第10点描述了顺序:1)大多数派生基类,2)直接基类初始化,3)非静态数据成员4)构造函数的复合语句。

This means that the base class(es of your class) are always initialised when your data member brace-or-equal-initializer is called. 这意味着在调用数据成员brace-or-equal-initializer时,始终会初始化基类(类的类)。

Point 13 of the section says: "Member functions (including virtual member functions) can be called for an object under construction." 该部分的第13点说: “可以为正在建造的对象调用成员函数(包括虚拟成员函数)。” ... "However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the result of the operation is undefined. ". ...“但是,如果在基类的所有mem-initializer完成之前,在ctor-initializer(或直接或间接从ctor-initializer中调用的函数)中执行这些操作,则操作的结果是不确定的。“ This last exception should not happen in your case. 在您的情况下不应该发生最后一个异常。

So yes, this kind of statement should be valid. 所以是的,这种陈述应该是有效的。

Edit: According to 12.6.2 pt.8, the brace-or-equal-initaliszer is only used if the constructor of the object does not have a mem-initializer for the member (ie the initializer with ":" syntax) 编辑:根据12.6.2 pt.8,仅当对象的构造函数没有成员的mem-initializer时(即具有“:”语法的初始化程序),才使用大括号或等于initaliszer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM