在C++中重载类的赋值运算符时,它的参数必须是引用吗?
例如,
class MyClass {
public:
...
MyClass & operator=(const MyClass &rhs);
...
}
Run Code Online (Sandbox Code Playgroud)
是真的吗
class MyClass {
public:
...
MyClass & operator=(const MyClass rhs);
...
}
Run Code Online (Sandbox Code Playgroud)
?
谢谢!
我最近重新访问了复制构造函数,赋值运算符,这里看到的复制交换idom: 什么是复制和交换习惯用法? 和许多其他地方 -
上面的链接是一个很好的帖子 - 但我还有一些问题 - 这些问题可以在很多地方,stackoverflow和许多其他网站上得到解答,但我没有看到很多一致性 -
1 - 您是否应该try- catch在我们为复制构造函数中的深层复制分配新内存的区域周围?(我已经看到了两种方式)
2 - 关于复制构造函数和赋值运算符的继承,何时应该调用基类函数,何时这些函数应该是虚函数?
3 - std::copy复制构造函数中复制内存的最佳方法是什么?我已经看过了memcpy,看到其他人说memcpy世界上最糟糕的事情.
考虑以下示例(感谢所有反馈),它提示了一些其他问题:
4 - 我们应该检查自我分配吗?如果是这样的话
5 - 关闭主题问题,但我看到swapped用作:
std::copy(Other.Data,Other.Data + size,Data);
应该是:
std::copy(Other.Data,Other.Data + (size-1),Data);
如果swap从'First到Last'而第0个元素是Other.Data?
6 - 为什么注释掉的构造函数不起作用(我必须将大小更改为mysize) - 假设这意味着无论我编写它们的顺序如何,构造函数将始终首先调用分配元素?
7 - 对我的实施还有其他评论吗?我知道代码没用,但我只想说明一点.
class TBar
{
public:
//Swap Function
void swap(TBar &One, TBar &Two)
{
std::swap(One.b,Two.b);
std::swap(One.a,Two.a);
}
int a;
int *b;
TBar& operator=(TBar Other)
{
swap(Other,*this);
return (*this);
}
TBar() : …Run Code Online (Sandbox Code Playgroud) 这是C++ Primer第5版的练习:
练习13.53:作为低效率的问题,HasPtr 赋值运算符并不理想.解释为什么.为HasPtr实现一个复制赋值和移动赋值运算符,并比较新移动赋值运算符和复制交换版本中执行的操作.(P.544)
档案hasptr.h:
//! a class holding a std::string*
class HasPtr
{
friend void swap(HasPtr&, HasPtr&);
friend bool operator <(const HasPtr& lhs, const HasPtr& rhs);
public:
//! default constructor.
HasPtr(const std::string &s = std::string()):
ps(new std::string(s)), i(0)
{ }
//! copy constructor.
HasPtr(const HasPtr& hp) :
ps(new std::string(*hp.ps)), i(hp.i)
{ }
//! move constructor.
HasPtr(HasPtr&& hp) noexcept :
ps(hp.ps), i(hp.i)
{ hp.ps = nullptr; }
//! assignment operator
HasPtr&
operator = …Run Code Online (Sandbox Code Playgroud) c++ rvalue-reference assignment-operator move-semantics c++11
我正在阅读关于raw_storage_iterator组件的TC++ PL .使用此组件可以获得性能优势,因为它可以避免分配(更昂贵)并使用复制构造.在我看来它应该在序列/容器中使用,在那里我们可以有大量的元素,因此赋值调用的数量可能会产生很大的影响.
理论上它很明确,它在我看来这个组件对容器类型类很有用.但是,我想了解我们应该在位详细信息中使用此组件(带有实际示例)以获得其性能优势?
中有很多操作std::ops,但没有简单的任务需要执行。
我来自C ++背景,那里有复制构造函数和赋值运算符重载,它们可以为您完成工作。我在Rust中需要类似的东西。
我想知道=+和+=(和其他任务操作员)之间是否存在差异.我试过,两个都做了同样的事情.那么有区别还是有约定?两者都有效,因为我的编译器没有检查标准吗?
编辑:我犯了一个错误.我在测试期间使用了不良输入,这让我觉得他们都在做同样的事情.原来他们是两件不同的事情.该+=运营商增加了右值到左值=+.=+只需将右值分配给左值+=.
struct do_nothing
{
template <class T>
void operator()(T*) {}
};
int
main()
{
int i = 0;
std::unique_ptr<int, do_nothing> p1(&i);
std::unique_ptr<int> p2;
static_assert(!std::is_assignable<decltype(p2), decltype(p1)>::value, ""); // note ! here.
}
Run Code Online (Sandbox Code Playgroud)
如果表达式
std::declval<T>() = std::declval<U>()在未评估的上下文中格式良好,则提供成员常量值等于true.否则,值为false.从与任一类型无关的上下文执行访问检查.
template<class T>
typename std::add_rvalue_reference<T>::type declval() noexcept;
Run Code Online (Sandbox Code Playgroud)
返回类型是
T&&除非T(可能是cv-qualified)void,在这种情况下返回类型是T.
我们来看看MoveAssignOnly:
struct MoveAssignOnly {
MoveAssignOnly &operator=(MoveAssignOnly &) = delete;
MoveAssignOnly &operator=(MoveAssignOnly &&) = default;
};
int main()
{
static_assert(
not std::is_assignable<MoveAssignOnly, MoveAssignOnly>::value, "");
}
Run Code Online (Sandbox Code Playgroud)
现场演示: …
Rust 有几个不能链接的运算符(==例如<)。
但赋值运算符= 可以被链接起来。
a = b = 10;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,10 被分配给b,单位()被分配给a。
=Rust 允许我们这样链接有什么原因吗?
我为此创建了Clippy 问题 6576 。
例如,赋值运算符std::slice_array:
void operator=(const valarray<T>&) const; //#1
void operator=(const T&) const; //#2
const slice_array& operator=(const slice_array&) const; //#3
Run Code Online (Sandbox Code Playgroud)
#1并#2返回void,但#3返回const slice_array&。
它禁止某些代码,例如:
std::valarray<int> va{1, 2, 3, 4, 5, 6};
va[std::slice(3, 2, 2)] = va[std::slice(0, 2, 2)] = va[0];
Run Code Online (Sandbox Code Playgroud)
为什么?
我正在处理分配内存供内部使用的对象。目前,它们不可复制。
例如
class MyClass
{
public:
MyClass() { Store = new int; }
~MyClass() { delete Store; }
private:
int* Store;
};
Run Code Online (Sandbox Code Playgroud)
我想添加允许分配所需的内容,既具有复制语义又具有移动语义,并且还能够将它们存储在向量中(具有移动语义)。我不想使用智能指针,并希望保持简单。
我应该定义哪些类成员?如何强制复制分配或移动分配?按值或按引用传递对象时将执行哪个副本?C++ 的连续版本之间的实现会有所不同吗?
例如
MyClass A, B;
A = B; // How to force copy or move ?
std::vector<MyClass> V = { A, B };
Run Code Online (Sandbox Code Playgroud) c++ ×7
c++11 ×2
deep-copy ×2
rust ×2
c ×1
constructor ×1
inheritance ×1
move ×1
performance ×1
reference ×1
valarray ×1