我需要创建一个Bar
对象,其中有一个私有对象Foo f
。
但是,Foo
对象参数的值应由特定方法int genValue()
传递。
如果我在构造函数作用域f
中初始化Bar(){...}
,则会引起编译器大喊错误,就像没有构造函数Foo()
一样。
如果我这样构造Bar(): f(genValue())
,则编译器会大喊错误:
test.cpp:在构造函数“ Bar :: Bar()”中:
test.cpp:16:19:错误:无法将类型为'int&'的非常量左值引用绑定至类型为'int'的右值
Bar():f(genValue()){
~~~~~~~~ ^^test.cpp:7:2:注意:初始化“ Foo :: Foo(int&)”的参数1
Foo(int&x){
^ ~~
class Foo {
public:
Foo(int &x) {
this->x = x;
}
private:
int x;
};
class Bar {
public:
Bar(): f(genValue()){
}
private:
Foo f;
int genValue(){
int x;
// do something ...
x = 1;
return x;
}
};
int main() {
Bar bar ();
return 0;
}
如果我不想修改Foo
类并且应该从genValue()
传递其参数值,该如何解决该问题?而且,我不想使用纯指针(*),但是使用智能指针的解决方案是可以的!
答案 0 :(得分:1)
您所写的Foo
类型是垃圾。这会导致您的错误。
Foo(int &x) {
this->x = x;
}
(a)这里绝对没有理由引用x
,而(b)更少理由引用非const
。
以下任何一项都可以修复Foo
和您的错误。
Foo(int const&x) {
this->x = x;
}
Foo(int const&x_in):x(x_in) {
}
Foo(int x) {
this->x = x;
}
Foo(int x_in):x(x_in) {
}
,并且,如果该值实际上不是int
却很便宜:
Foo(int x) {
this->x = std::move(x);
}
Foo(int x_in):x(std::move(x_in)) {
}
这些是针对您的问题的6种独立解决方案。
对于int
,我将使用#4;非int
#6。
在Foo
之外修复此错误是一个坏主意,因为您会因为 Foo
错误而出错。您其余的代码很好,请避免破坏好的代码。
答案 1 :(得分:1)
不要传递int&
,它不能绑定到常量或临时对象,因为它们不能被修改-请改用const int&
。
实际上,对于简单类型,您应该更喜欢按值传递,而让优化器担心提供最佳实现。
答案 2 :(得分:1)
非{const
的引用参数(例如int&
)只能引用“左值”,这是一个以命名的变量。
auto takes_nonconst_reference = [](int&){};
auto takes_const_reference = [](const int&){};
auto takes_value = [](int){};
auto returns_int = []{return 42;};
int foo = 1;
// OK
takes_nonconst_reference(foo);
takes_const_reference(foo);
takes_const_reference(returns_int());
takes_value(foo);
takes_value(returns_int());
// compilation error, value returned from a function is not a named variable
takes_nonconst_reference(returns_int());
在这种情况下,由于您的类存储了构造函数参数的副本,因此应按值(int
,int&
或const int&
)传递它。