为什么赋值运算符会做与其匹配的构造函数不同的事情?

发布于 2024-09-01 08:15:56 字数 419 浏览 7 评论 0原文

我正在阅读一些 boost 代码,并发现了这一点:

inline sparse_vector &assign_temporary(sparse_vector &v) {
    swap(v);
    return *this;
}
template<class AE>
    inline sparse_vector &operator=(const sparse_vector<AE> &ae) {
        self_type temporary(ae);
        return assign_temporary(temporary);
    }

它似乎将所有构造函数映射到赋值运算符。伟大的。但为什么 C++ 选择让它们做不同的事情呢?我能想到的就是scoped_ptr?

I was reading some boost code, and came across this:

inline sparse_vector &assign_temporary(sparse_vector &v) {
    swap(v);
    return *this;
}
template<class AE>
    inline sparse_vector &operator=(const sparse_vector<AE> &ae) {
        self_type temporary(ae);
        return assign_temporary(temporary);
    }

It seems to be mapping all of the constructors to assignment operators. Great. But why did C++ ever opt to make them do different things? All I can think of is scoped_ptr?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情深如许 2024-09-08 08:15:56

为什么 C++ 选择让它们做不同的事情?

因为赋值适用于完全构造的对象。在资源管理类中,这意味着每个成员指针都已经指向一个资源。将此与构造函数进行对比,其中成员在执行之前没有任何意义。

顺便说一下,在 C++ 的早期,T a(b); 实际上被定义为 T a; a = b;,但这被证明是低效的,因此引入了复制构造函数。

why did C++ ever opt to make them do different things?

Because assignment works on a fully constructed object. In resource managing classes, this means that every member pointer already points to a resource. Contrast this to a constructor, where the members don't have any meaning prior to executing it.

By the way, in the very early days of C++, T a(b); was actually defined as T a; a = b;, but this proved to be inefficient, hence the introduction of the copy constructor.

国际总奸 2024-09-08 08:15:56

请注意,名称“assign_temporary”表示分配来自临时对象,因此可以在分配过程中销毁。赋值运算符采用一些您稍后可能想要使用的常规对象,因此不能在赋值期间销毁它。在此 Boost 代码中,“assign_temporary”与 右值引用 赋值运算符同义,而上面显示的赋值运算符是标准 const(左值)引用赋值运算符,因此您会期望两者之间存在这种不匹配。

不过,我同意,赋值运算符通常是使用复制和交换技巧来实现的(使用复制构造函数创建一个副本,然后与该副本进行交换)。但是,该标准已经定义了编译器在没有显式定义的情况下自动实现赋值运算符的方法,因此更改默认实现可能会破坏现有代码。

Notice the name "assign_temporary" indicates that the assignment is from an object that is temporary and therefore can be destroyed in the process of assignment. The assignment operator takes some regular object that you might want to use later, so it is not an option to destroy it during the assignment. In this Boost code, "assign_temporary" is synonymous with the rvalue reference assignment operator, while the assignment operator that you have shown above is the standard const (lvalue) reference assignment operator, so you would, therefore, expect this kind of mismatch between the two.

I agree, though, the assignment operator is typically implemented using the copy and swap trick (create a copy with the copy constructor, then swap with the copy). However, the standard already defines the automatic implementation of the assignment operator by the compiler in the absence of an explicit definition, and so changing the default implementation would potentially break existing code.

一笑百媚生 2024-09-08 08:15:56

正是因为有时不允许分配甚至复制某些类。例如,使用 RAII,您可以构建一个互斥类,该互斥类打开一个锁,然后在到期时关闭该锁。如果允许您复制或分配这样的类,您可以想象将其传递到函数作用域之外。这可能会在坏人手中造成坏事。

For the very reason that some classes sometimes shouldn't be allowed to be assigned or even copied. For instance, using RAII you can build a mutex class which opens a lock and then closes the lock upon expiration. If you were allowed to copy or assign such a class you could conceivably pass it outside of the function scope. This could cause bad things in the hands of bad people.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文