分配操作员返回值类型

assignment operator returning value type

本文关键字:类型 返回值 操作员 分配      更新时间:2023-10-16

我是偶然发现的,分配操作员不是返回参考,而是副本作为解决方法,可以在STL容器中使用const成员存储对象。

class Test_class
{
public:
    int const whatever;
    explicit Test_class(int w) : whatever(w) {}
    // note the missing &
    Test_class operator=(Test_class const& rhs) {
        return Test_class(rhs.whatever);
    }
};
vector<Test_class> vec;
Test_class foo(42);
vec.push_back(foo);
assert(vec[0].whatever == 42);

这件代码感觉非常奇怪,但是GCC编译了它,并且似乎可以正常工作。

那么陷阱在哪里?

编辑:

push_back() vec[0].whatever实际上是42.添加了一个插图的断言。

编辑:

感谢您的答案!只是为了乐趣,此版本也可以很好地运行;)

void operator=(Test_class const&) {
    throw 42;
}

算法超载的大多数接受惯例不是由标准或编译器强制执行的。这只是对行为的期望。您可以在此处查看其中的一些:操作员过载或这里:http://en.cppreference.com/w/cpp/language/operators。

这里的陷阱是您的operator=并不是真正的分配操作员。考虑此代码:

Test_class a(15);
Test_class b(20);
a = b;

通常,执行此代码后,您希望a.whatever是20岁,但是它仍然是15。

c 03要求向量元素既可以使用拷贝性构建,又是可复制的,并且编译器可以自由选择使用的内容。在C 11中,它们仅必须是可复制构造(或移动构造),因此不需要分配操作员。

您实际上没有在这里分配任何内容。您甚至可以将该分配运算符声明为const,因为它无济于事。

Test_class a(17);
Test_class b(33);
a = b; // nothing happens.  

运算符的返回值=并不重要,我通常将其声明为 void。只有执行诸如a = b = c;之类的事情,这只是很重要的事情,这不是很常见。使用您的operator=,这将编译,但同样,根本没有做任何事情。