Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to do some computation in the constructor function body other than Initialization list

Tags:

c++

I know usually it's better to rely on the initialization list,

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) {}
 }

Now it's possible to initialize some class B objects with

B b(vector_x, vector_y);

But if in the constructor of B, the initialization "A a2" requires some computation with vector_x and vector_y, then,

is it possible to do it in the constuctor function body?

or should I call some function in the initialization list?

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

What are the best ways to do something like this?

like image 222
lorniper Avatar asked Dec 12 '25 11:12

lorniper


2 Answers

Since class A doesn't have a default constructor, this example code will not compile:

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

And if you can't redesign class A then you have to pass it an object in memory, where the expression is an lvalue.

However, since the reference to non-const passed to the A constructor is not retained, you can simply do

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

If you can instead fix class A then that's best, then you can do

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

or even

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

If f is a real function that you have available, or can practically make available, then you can now (after fixing A) also just do

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 ) )
{}

placing that call in the initializer list.

like image 64
Cheers and hth. - Alf Avatar answered Dec 14 '25 01:12

Cheers and hth. - Alf


Yes, you can call a function in a constructor initialization list.

Assuming you can change the constructor of A to take a const reference you can write:

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)) { }
};
like image 24
Chris Drew Avatar answered Dec 14 '25 02:12

Chris Drew



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!