可以使用成员函数在初始化列表中初始化成员变量? [英] can member functions be used to initialize member variables in an initialization list?

查看:195
本文介绍了可以使用成员函数在初始化列表中初始化成员变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

OK,成员变量可以用于初始化初始化列表中的其他成员变量(注意初始化顺序等)。成员函数怎么办?具体来说,根据C ++标准,此代码段是否合法?

  struct foo {
foo(const size_t N ):N_(N),arr_(fill_arr(N)){
// arr_ = fill_arr(N); //或者我应该回到这一个吗?
}

std :: vector< double> fill_arr(const size_t N){
std :: vector< double> arr(N)。
//向量填充
return arr;
}

size_t N_;
std :: vector< double> arr_;
//其他东西
};


解决方案

是的,您在初始化列表中使用成员函数有效且符合标准。



数据成员按其声明的顺序初始化(这就是为什么它们应按照它们的顺序出现在初始化列表中的原因)声明 - 您在示例中遵循的规则)。 N _ 首先被初始化,您可以将此数据成员传递给 fill_arr fill_arr 在构造函数之前调用,但因为此函数不访问未初始化的数据成员(它根本不访问数据成员),因此它的调用是安全的。



以下是C ++标准的最新草案(N3242 = 11-0012)的一些相关例外:


< (...)但是,如果这些操作是在一个ctor-initializer中执行的,或者是在一个ctor-initializer中执行的,在基本类的所有
mem初始化器完成之前,直接或间接地从ctor-initializer调用函数

操作的结果是未定义的。示例:




  class A {public:A }; 

class B:public A {
int j;
public:
int f();
B():A(f()),//未定义:调用成员函数
//但是基本A尚未初始化
j(f()){} // :基本都初始化
};

class C {
public:
C(int);
};

class D:public B,C {
int i;
public:
D():C(f()),//未定义:调用成员函数
//但是基本C尚未初始化
i(f } //很好定义:基本都初始化
};




§12.7.1:对于具有非平凡构造函数的对象,在
构造函数开始执行之前引用
对象的任何非静态成员或基类,会导致未定义的行为。示例




  struct W {int j; }; 
struct X:public virtual W {};
struct Y {
int * p;
X x;
Y():p(& x.j){// undefined,x尚未构建
}
};


OK, member variables can be used to initialize other member variables in an initialization list (with care taken about the initialization order etc). What about member functions? To be specific, is this snippet legal according to the C++ standard?

struct foo{
  foo(const size_t N) : N_(N),  arr_(fill_arr(N)) { 
    //arr_ = fill_arr(N); // or should I fall back to this one?
  }

  std::vector<double> fill_arr(const size_t N){
    std::vector<double> arr(N);
    // fill in the vector somehow
    return arr;
  }

  size_t N_;
  std::vector<double> arr_;
  // other stuff
};

解决方案

Yes, your use of member function in initialization list is valid and complies with the standard.

Data members are initialized in the order of their declaration (and that's the reason why they should appear in the initialization list in the order of their declaration - the rule that you followed in your example). N_ is initialized first and you could have passed this data member to fill_arr. fill_arr is called before constructor but because this function does not access uninitialized data members (it does not access data members at all) its call is considered safe.

Here are some relevant excepts from the latest draft (N3242=11-0012) of the C++ standard:

§ 12.6.2.13: Member functions (including virtual member functions, 10.3) can be called for an object under construction.(...) 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. Example:

class A { public:    A(int); };

class B : public A {
   int j;
public:
   int f();
   B() : A(f()), // undefined: calls member function
                 // but base A not yet initialized
   j(f()) { }    // well-defined: bases are all initialized
};

class C {
public:
   C(int);
};

class D : public B, C {
   int i;
public:
   D() : C(f()), // undefined: calls member function
                 // but base C not yet initialized
   i(f()) { } // well-defined: bases are all initialized
};

§12.7.1: For an object with a non-trivial constructor, referring to any non-static member or base class of the object before the constructor begins execution results in undefined behavior. Example

struct W { int j; };
struct X : public virtual W { };
struct Y {
   int *p;
   X x;
   Y() : p(&x.j) { // undefined, x is not yet constructed
   }
};

这篇关于可以使用成员函数在初始化列表中初始化成员变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆