can member functions be used to initialize member variables in an initialization list?

て烟熏妆下的殇ゞ 提交于 2019-11-27 10:46:55

问题


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
};

回答1:


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
   }
};



回答2:


While initializing objects in the initialization list, the object is not yet fully constructed.
If those function tries to access the part of the object which is not yet constructed then that is a undefined behavior else its fine.
see this answer.



来源:https://stackoverflow.com/questions/11174129/can-member-functions-be-used-to-initialize-member-variables-in-an-initialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!