C++ 是否可以在构造函数函数体中执行初始化列表以外的计算
我知道通常最好依靠初始化列表C++ 是否可以在构造函数函数体中执行初始化列表以外的计算,c++,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
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的构造函数中,初始化“a2”需要一些向量x和向量y的计算,那么
是否可以在构造函数函数体中执行此操作
还是应该调用初始化列表中的某个函数
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?
}
}
B类{
公众:
A a1;
A a2;
B(标准向量&x,标准向量&y):a1(x)
{
//执行类似于f(x,y)的操作,并初始化a2?如何初始化?
}
}
这样做的最佳方法是什么?但是如果在B的构造函数中,初始化“ab”需要使用向量x和向量y进行一些计算,那么
该计算将在初始化之后进行,而不是同时进行
是的,您可以在B构造函数的主体内进行计算。构造函数是函数的一种类型
顺便说一句,最好将您的成员变量置于私有作用域下。因为类
a
没有默认构造函数,所以此示例代码不会编译:
B( std::vector<double>& x,std::vector<double>& y )
: a1( x )
{
//do something like f(x,y), and initialize a2? how?
}
如果您可以改为修复类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 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()
}
}
B类
{
std::唯一的ptr a1;
std::唯一的ptr a2;
公众:
B(vecx,vexy):a1{newa{x}}
{
a2.reset(新的A{f(x,y)});//用f()的结果构造a2
}
}
这是假设函数
f()
是B
..的成员。是的,您可以调用构造函数初始化列表中的函数
假设您可以更改A
的构造函数以获取常量引用,您可以编写:
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)) { }
};
A类{
std::向量X;
公众:
A(const std::vector&x):x(x){}
};
B类{
A a1;
A a2;
公众:
B(常数std::vector&x,常数std::vector&y):a1(x),a2(f(x,y)){
};
如果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){}
};
我为错误感到抱歉…如果
f(x,y)
是无状态的,那么你不能做B(std::vector&x,std::vector&y):a1(x),a2(f(x,y)){}
的任何原因都是可能的(你试过了吗?),有时也是必要的。然而,有些人认为最好只做最简单的事情,在构造函数中将对象置于合法状态,在成员函数中将对象置于更复杂的状态。@Galik Why Books link?@Component10“f(x,y)是无状态的”是什么意思?也许您可以发布一个代码片段。@lorniper:所谓无状态,我的意思是f(x,y)
将不依赖于您正在构造的对象的状态(变量值等)。使用指针有什么意义。没有构造函数也可以这样做。@doc不,因为A
没有默认构造函数。@ChrisDrew不能简单地调用初始化器列表中的a2(f(x,y))
。@doc是的,你可以这样做,但这是一个不同的答案,我的答案:)不过使用指针的目的是将初始化推迟到构造函数的主体。同意,但这个例子并没有明确说明这一点。@ChrisDrew你也可以在初始值设定项列表中执行a2(新的A(f(x,y))
,所以我仍然不明白这个答案的意义。@lorniper:我确实是指a2
。不确定你说的没有添加A(){}
是什么意思,我就是这么做的?无论如何,谢谢@洛尼珀:哦。我一次只改变一件事,就像科学方法一样。这使我们更容易看到每次变化的效果。添加默认构造函数会改变类a
的使用,因此这是一件更激烈的事情。谢谢,添加默认构造函数以便在初始化列表中使用a2()?顺便说一句,你用a2.X,而你用的是固定的X,谢谢。我不知道这些打字错误是从哪里来的。键盘恶魔抱怨…@lorniper:你应该发布一个新问题,因为您现在描述的代码听起来与所提供的代码完全不同。请注意,对于OP的代码,只有当f
返回对non-const
@cheers和hth的引用时,这才有效。-Alf我假设a
接受非const引用没有充分的理由。但是说得好,谢谢!f的区别是什么?如果是常量引用还是非常量引用?@lorniper您不能将临时引用绑定到非常量引用。我假设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 ) )
{}
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()
}
}
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)) { }
};
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){}
};
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) {}
};