是否可以在构造函数体中除初始化列表之外进行一些计算

时间:2015-01-16 14:01:09

标签: c++

我知道通常最好依赖初始化列表

class A {
  public:
    std::vector<double> X;
    A(std::vector<double> &x ) : X(x) {/.../}
};

class B {
   public:
   A a1;
   A a2;
   B(std::vector<double> &x,std::vector<double> &y ) : a1(x),a2(y) {}
 }

现在可以使用

初始化一些B类对象
B b(vector_x, vector_y);

但是如果在B的构造函数中,初始化&#34; A a2&#34;需要用vector_x和vector_y进行一些计算,然后

是否可以在constuctor函数体中进行?

还是应该在初始化列表中调用某个函数?

class B {
       public:
       A a1;
       A a2;
       B(std::vector<double> &x,std::vector<double> &y ) : a1(x)
       {
        //do something like f(x,y), and initialize a2? how? 
       }
     }

做这样的事情的最佳方法是什么?

5 个答案:

答案 0 :(得分:1)

由于类A没有默认构造函数,因此该示例代码将无法编译:

B( std::vector<double>& x,std::vector<double>& y )
    : a1( x )
{
    //do something like f(x,y), and initialize a2? how? 
}

如果你不能重新设计类A,那么你必须在内存中传递一个对象,其中表达式是左值。

但是,由于不保留对传递给const构造函数的非A的引用,您只需执行

template< class Type >
auto temp_ref( Type&& o ) -> Type& { return o; }

B( std::vector<double>& x,std::vector<double>& y )
    : a1( x )
    , a2( temp_ref( std::vector<double>() ) )
{
    a2.X = f(x,y);
}

如果您可以修改课程A,那么最好,那么您可以

class A
{
public:
    std::vector<double> x;
    A( std::vector<double> const& _x ) : x( _x ) {}
};

B( std::vector<double>& x,std::vector<double>& y )
    : a1( x )
    , a2( std::vector<double>() )
{
    a.x = f(x,y);
}

甚至

class A
{
public:
    std::vector<double> x;
    A() {}
    A( std::vector<double> const& _x ) : x( _x ) {}
};

B( std::vector<double>& x,std::vector<double>& y )
    : a1( x )
    , a2()
{
    a2.x = f(x,y);
}

如果f是您可用的实际功能,或者实际上可以使用,那么您现在可以(在修复A之后)也可以

class A
{
public:
    std::vector<double> x;
    //A() {}    -- Add if it is meaningful for the use of A.
    A( std::vector<double> const& _x ) : x( _x ) {}
};

B( std::vector<double>& x,std::vector<double>& y )
    : a1( x )
    , a2( f( x, y ) )
{}

将该调用放入初始化列表中。

答案 1 :(得分:1)

是的,您可以在构造函数初始化列表中调用函数。

假设您可以更改A的构造函数以获取const引用,您可以写:

class A {
    std::vector<double> X;
  public:
    A(const std::vector<double>& x ) : X(x) { }
};

class B {
  A a1;
  A a2;
 public:
  B(const std::vector<double>& x, const std::vector<double>& y) : a1(x), a2(f(x,y)) { }
};

答案 2 :(得分:0)

但是如果在B的构造函数中,初始化&#34; A b&#34;需要使用vector_x和vector_y进行一些计算,然后......

计算将在初始化之后完成,而不是在同一时间完成。

而且,是的,你可以在B构造函数体内进行计算。构造函数是一种函数。

顺便说一下,将成员变量放在私有范围内是个好主意。

答案 3 :(得分:0)

您可以使用指针..

class B
{
  std::unique_ptr<A> a1;
  std::unique_ptr<A> a2;

public:

  B(vec x, vex y) : a1{new A{x}}
  {
    a2.reset(new A{f(x, y)}); // construct a2 with the result of f()
  }
}

这假设函数f()B ...

的成员

答案 4 :(得分:0)

如果A2需要用x和y进行一些计算,则它是A2,这应该提供足够的构造函数

class A {
 public:
    std::vector<double> X;
    A(std::vector<double> &x) : X(x) {}
    A(std::vector<double> &x, std::vector<double> &y ) : X(x) {//do something with x, y}
};


class B {
    public:
     A a1;
     A a2;
     B(std::vector<double> &x,std::vector<double> &y ) : a1(x),a2(x, y){}
};

如果你想在a1a2初始化之前在B的初始化列表中对x和y做一些事情,你可以使用私有继承,但IMO并不是好设计的标志,它是没有意义的。

class F {
   public:
       F(std::vector<double> &x, std::vector<double> &y) {//f(x,y)}
};

class B : private F {
 public:
     A a1;
     A a2;
    B(std::vector<double> &x, std::vector<double> &y ) : F(x, y), a1(x), a2(y) {}
};
抱歉抱歉...