C++;:const从一个初始值设定项函数初始化多个数据成员 我有一个C++类,它有两个数据成员,例如 class mytest() { public: mytest(): a_(initA()), b_(initB()) {}; virtual ~mytest() {}; private: double initA() { // some complex computation } double initB() { // some other complex computation } private: const double a_; const double b_; }
不幸的是,C++;:const从一个初始值设定项函数初始化多个数据成员 我有一个C++类,它有两个数据成员,例如 class mytest() { public: mytest(): a_(initA()), b_(initB()) {}; virtual ~mytest() {}; private: double initA() { // some complex computation } double initB() { // some other complex computation } private: const double a_; const double b_; },c++,initialization,C++,Initialization,不幸的是,initA和initB不能像上面所描述的那样分开。a_和b_都可以通过一个大的复杂计算来初始化,其中b_的值取决于a_计算中的中间结果,例如 void mytest::init() const { const double a = 1.0 + 1.0; // some complex computation const double b = 2*(a + 1.0); // another complex computation a = 2 * a; // e
initA
和initB
不能像上面所描述的那样分开。a_
和b_
都可以通过一个大的复杂计算来初始化,其中b_
的值取决于a_
计算中的中间结果,例如
void mytest::init() const {
const double a = 1.0 + 1.0; // some complex computation
const double b = 2*(a + 1.0); // another complex computation
a = 2 * a; // even more complex, wow
// Now, a and b contain the data from which a_ and b_ should be initialized.
}
我希望将
a_
和b_
分开(和const
)变量(而不是将它们放在std::tuple
或类似的变量中)。但是,我不知道是否可以从单个函数中分别初始化a_
和b_
有什么提示吗?我的建议可能看起来很明显,但绝对没有必要对您的成员变量使用
const
。如果希望类型是不可变的,只需不提供setter方法,并在构造函数中计算成员的值即可
class mytest() {
public:
mytest() {
a_ = 1.0 + 1.0; // some complex computation
b_ = 2.0 *(a + 1.0); // another complex computation
a_ = 2.0 * a_; // even more complex, wow
};
// Make your methods const to prevent modification of the members
void testMethod() const {
// a_ = 20.0; // Will result in an error!
std::cout << "sum = " << a_ + b_ << '\n'; // perfectly fine
}
virtual ~mytest() {};
private:
double a_;
double b_;
};
classmytest(){
公众:
我的测试(){
a=1.0+1.0;//一些复杂的计算
b_=2.0*(a+1.0);//另一个复杂的计算
a=2.0*a;//更复杂,哇
};
//将方法设置为常量以防止修改成员
void testMethod()常量{
//a_=20.0;//将导致错误!
std::cout你总是可以扔掉常数,但我真的会重新考虑你的设计,而不是去做
// some pointer
double *ptr;
// give it the value of '_a'
ptr = (double*)( &_a );
// change the value now
*ptr = 5.34;
也在你的代码中
const double a = 1.0 + 1.0;
应该是
double a = 1.0 + 1.0;
不需要常量。您可以添加额外的中间函数/结构来初始化类
使用委托构造函数:
struct MytestHelper
{
double a;
double b;
};
MytestHelper someComplexComputation(); // feed `a` and `b`
class mytest() {
public:
mytest() : mytest(someComplexComputation()) {}
virtual ~mytest() {};
private:
mytest(const MytestHelper& h) : a_(h.a), b_(h.b) {}
private:
const double a_;
const double b_;
};
首先,您需要初始化构造函数中初始值设定项列表中的const成员,而不是在某些成员函数中,a_
和b_
应该由构造函数初始化:mytest():a_40; valueA),b_41;(valueB){
其中valueX
可以是直接值、构造函数中的参数或返回计算值的函数。此外,还有一个名为init
的函数:当实例化一个对象时,将调用构造函数,并在该对象初始化后调用。这就像有一个名为deinit
的函数h应该在析构函数之前被调用…no senseJ必须在初始化列表中初始化它们。如果你不能,那么显示一些相关的代码。我认为没有必要使成员常量
。你能解释一下为什么你认为这是必要的吗?正如@Angew在下面对我的答案的评论中指出的,它们阻止了移动可分配性并带来了几乎没有什么好处。@Nasser我不知道有两个双精度的类型是不可移动的有什么关系。我认为,即使是你自己,你也不应该允许人们修改不可修改的东西(我不是选民们的想法:-P)我同意。const
成员的麻烦比他们的价值大得多。他们阻止了移动可分配性,并没有带来什么好处。我的首选是尽可能地使用const
。这使得对变量进行推理变得更容易(对我和编译器而言)。无论如何,我的大多数类都是显式不可复制或分配的。OP中的代码当然是实际代码的根本简化。这是如此复杂,以至于需要const
,以防止开发人员错误地意外重写有问题的变量。@NicoSchlömer我认为这是可能的,但它消除了创建常量成员变量所带来的复杂性。目前为止的所有其他答案(无意冒犯)最后,我建议你对你的开发团队有一点信心,因为如果你不能信任他们为不可变类型创建方法const
,那么随着你的项目的发展,你将获得一些真正的调试乐趣。我想说constdouble a=1.0+1.0
应该是constepr double a=1.0+1.0
Brilliant!在“计算机科学中的所有问题都可以通过添加另一层间接(除了太多的间接)来解决”的(长)列表中添加另一个例子。我将无法使用第一个建议,因为b
取决于someComplexComputation()的中间结果
。不过,委托构造函数就可以了。我可以建议删除第一个建议吗?OP已经澄清,他理解这种方法,但这两个变量的计算是密切相关的,不能像那样分成两个函数。