如何使用带有引用的 operator=

How to use operator= with a reference

提问人:George Kourtis 提问时间:8/26/2014 最后编辑:CommunityGeorge Kourtis 更新时间:8/27/2014 访问量:133

问:

下面的代码与问题有关:在已回答的变量定义中使用的重载运算符=中出现错误看似不一致的行为。 我的问题是在尝试使用整数定义和初始化对结构的引用的上下文中提出的。

所以我需要写“S s1=3”;我需要写“S&s1=3”,我将如何管理它;

struct S{
    int a,b;
    void operator=(int x){a=x;b=x*x;}
    S(){};
    S(int x){a=x;b=x*x;}
};

int main(){
    S s1;s1=5;
    S s2;s2=7;
    S s3=9;
    S s4;
}

main() 的代码应修改如下:

int main(){
    //S s0=S{15,20};
    S s1;s1=5;
    S s2;s2=7;
    S s3=9;
    S s4;

    S& s5;s5=10;
    S& s6=10;
}

但是编译我有错误:

main.cpp:16:5:错误:“s5”声明为引用但未初始化

main.cpp:17:8:错误:从“int”类型的右值初始化类型为“S&”的非常量引用无效(关于 S6)。

C++语言

评论

0赞 Bathsheba 8/26/2014
S& s1=3这真的没有意义,因为它会导致超出范围的匿名临时的悬空。
0赞 chris 8/26/2014
S s1=3;不使用 .你的重载至少应该返回正确的类型。operator=
0赞 Mike Seymour 8/26/2014
你不能;必须初始化对 的引用才能引用 类型的现有对象。你认为你为什么需要这样做?SS
0赞 George Kourtis 8/26/2014
@MikeSeymour 真正的问题是我有一个 S 数组 (S A[0x10] ),通过写 S& s6=5,我想表示 S& s6=A[5];我能做到吗?
1赞 Mike Seymour 8/26/2014
@GeorgeKourtis:所以,如果这是你想说的,那就写吧。这个数字不可能意味着.S& s6=A[5];5A[5]

答:

1赞 M.M 8/26/2014 #1

这是不可能的;引用必须引用对象。您可以执行以下任一操作(使用 C++98 语法):

S const &s1 (3);   // same as S const &s1 = S(3);

S s0(3); S &s1(s0);
3赞 Piotr Skotnicki 8/26/2014 #2

首先,您没有使用 ,而是复制初始化operator=

也就是说,表达式使用非显式构造函数以及非显式且可访问的复制构造函数(希望没有任何额外的开销)。S s1 = 3;S(int x)S(const S& x)

更进一步,你不能使用,不是因为你不能将 3 赋值给引用,而是因为赋值的右侧是 R-VALUE(即临时值)。但是,您可以使用对 l 值的 const 引用来延长其生存期,因为 r 值非常喜欢受 const l 值引用的约束:S& s1 = 3;

const S& s1 = 3;

只要未标记为 ,这将起作用。S(int x)explicit

或者,(您根本不应该这样做),您可以使用 r 值引用:

S&& s1 = 3; // implicitly
S&& s2 = S(3); // explicitly

以及您在尝试编译时看到的错误:S& s5;

main.cpp:16:5: error: ‘s5’ declared as reference but not initialized

告诉你,你不能只创建一个作为引用(而不是指针)的变量,而不初始化它。

但是,如果你有一个有效初始化的引用,那么每当你使用赋值时,才会调用:operator=

S s1(1);
S& s1ref = s1;
S s2(2);
s1ref = s2; // s1.operator=(s2);

评论

0赞 M.M 8/26/2014
S s1 = 3;意味着,因此与 相比存在“开销”。临时的可以省略,但类仍必须具有可访问的复制/移动构造函数S s1 = S(3);S s1(3);
0赞 M.M 8/26/2014
下面是一个示例,显示复制构造函数是必需的
0赞 M.M 8/26/2014
这称为复制省略。它可能会被调用。
0赞 M.M 8/26/2014
顺便说一句,这也是为什么不能调用显式构造函数的原因(临时对象必须调用隐式构造函数,因为此对象未显式初始化)S(3)