分配对结构的引用
Assigning a reference to a struct
我有一个变量ntot_sols
,当我构造对象时,它的最终值是未知的。
因此,我想存储对变量的引用而不是值,因为它可能会发生变化。
我想下面的代码可以做到。
struct ItemWeighter {
int nsols;
int ntot_sols;
ItemWeighter(int _nsols, int& _ntot_sols) {
nsols = nsols;
ntot_sols = _ntot_sols;
}
float weight() {
return nsols / float(ntot_sols);
}
};
但令我惊讶的是 ntot_sols
是类型 int
而不是 int &
。变量如何知道它是一个引用?
不能使用赋值运算符绑定引用。它必须在首次创建时绑定。对于 class 成员变量,这意味着您必须在 member initializer list 中执行此操作;构造函数的主体来不及了。
示例:
#include <iostream>
class foo {
private:
int& x;
public:
foo(int& other_var) : x(other_var) { }
~foo() { }
void print_x() { std::cout << x << std::endl; }
};
int main() {
int a = 5;
foo my_foo(a);
my_foo.print_x();
a = 10;
my_foo.print_x();
return 0;
}
Try on godbolt。它打印出:
5
10
请注意,您的对象持有对在别处创建的另一个变量的引用的此类代码可能存在风险。您需要确保引用的 int
的生命周期至少与 foo
对象一样长。很容易出错,编译器不会帮助你。考虑例如:
foo make_a_foo() {
int a = 7;
foo f(a);
return f;
}
void other_func() {
foo g = make_a_foo();
g.print_x(); // undefined behavior!
}
这里 g.x
是对 make_a_foo()
的局部变量 a
的引用,其生命周期在 make_a_foo()
返回时结束。
毕竟让x
成为一个普通的int
成员变量,而不是引用,并在需要时调用setter函数来更新它的值可能会更好。
我有一个变量ntot_sols
,当我构造对象时,它的最终值是未知的。
因此,我想存储对变量的引用而不是值,因为它可能会发生变化。
我想下面的代码可以做到。
struct ItemWeighter {
int nsols;
int ntot_sols;
ItemWeighter(int _nsols, int& _ntot_sols) {
nsols = nsols;
ntot_sols = _ntot_sols;
}
float weight() {
return nsols / float(ntot_sols);
}
};
但令我惊讶的是 ntot_sols
是类型 int
而不是 int &
。变量如何知道它是一个引用?
不能使用赋值运算符绑定引用。它必须在首次创建时绑定。对于 class 成员变量,这意味着您必须在 member initializer list 中执行此操作;构造函数的主体来不及了。
示例:
#include <iostream>
class foo {
private:
int& x;
public:
foo(int& other_var) : x(other_var) { }
~foo() { }
void print_x() { std::cout << x << std::endl; }
};
int main() {
int a = 5;
foo my_foo(a);
my_foo.print_x();
a = 10;
my_foo.print_x();
return 0;
}
Try on godbolt。它打印出:
5
10
请注意,您的对象持有对在别处创建的另一个变量的引用的此类代码可能存在风险。您需要确保引用的 int
的生命周期至少与 foo
对象一样长。很容易出错,编译器不会帮助你。考虑例如:
foo make_a_foo() {
int a = 7;
foo f(a);
return f;
}
void other_func() {
foo g = make_a_foo();
g.print_x(); // undefined behavior!
}
这里 g.x
是对 make_a_foo()
的局部变量 a
的引用,其生命周期在 make_a_foo()
返回时结束。
毕竟让x
成为一个普通的int
成员变量,而不是引用,并在需要时调用setter函数来更新它的值可能会更好。