我想在编译器通常自动生成默认构造函数,复制构造函数和赋值运算符的条件下刷新内存.
我记得有一些规则,但我不记得了,也无法在网上找到有信誉的资源.有人可以帮忙吗?
c++ copy-constructor default-constructor move-constructor move-assignment-operator
在类的赋值运算符中,通常需要检查所分配的对象是否是调用对象,这样就不会搞砸了:
Class& Class::operator=(const Class& rhs) {
if (this != &rhs) {
// do the assignment
}
return *this;
}
Run Code Online (Sandbox Code Playgroud)
移动赋值运算符需要相同的东西吗?是否有过这样的情况this == &rhs?
? Class::operator=(Class&& rhs) {
?
}
Run Code Online (Sandbox Code Playgroud) 关于移动分配的标准库策略是允许实现假设永远不会发生自我分配 ; 在我看来这是一个非常糟糕的主意,因为:
remove_if家庭中的任何事情都需要照顾这个角落的情况;那么,为什么这样的决定呢?
¹特别是在库代码中,实现者可以自由地利用关于"分支预期结果"的编译器特定提示(在VC++ __builtin_expect中的gcc/__assume中).
这是使用移动构造函数为大多数类定义移动赋值的一种非常简单的方法:
class Foo {
public:
Foo(Foo&& foo); // you still have to write this one
Foo& operator=(Foo&& foo) {
if (this != &foo) { // avoid destructing the only copy
this->~Foo(); // call your own destructor
new (this) Foo(std::move(foo)); // call move constructor via placement new
}
return *this;
}
// ...
};
Run Code Online (Sandbox Code Playgroud)
这个调用你自己的析构函数的序列是否跟随在标准C++ 11中的this指针安全位置新增?
c++ placement-new move-semantics c++11 move-assignment-operator
与一起编译,/permissive但与一起失败/permissive-。什么不符合以及如何解决?
为什么很好,(2)但失败了?如果我删除它也很好。(4)(3)operator long
如何在不更改呼叫站点的情况下进行修复(3,4)?
#include <string>
struct my
{
std::string myVal;
my(std::string val): myVal(val) {}
operator std::string() { return myVal; };
operator long() { return std::stol(myVal); };
};
int main()
{
struct MyStruct
{
long n = my("1223"); // (1)
std::string s = my("ascas"); // (2)
} str;
str.s = my("ascas"); // (3)
str.n = my("1223"); // (4)
}
Run Code Online (Sandbox Code Playgroud)
错误信息
error C2593: 'operator =' is ambiguous
xstring(2667): note: could …Run Code Online (Sandbox Code Playgroud) c++ visual-c++ implicit-conversion move-constructor move-assignment-operator
我想创建一个包含迭代器类的列表数据结构。一切正常,但是当我声明移动赋值运算符时,如果程序使用 C++14 或 C++11 标准,则该程序不会编译,但在 C++17、C++2a 中运行良好。
列表.h:
#pragma once
#include <iostream>
template <typename T>
class list {
struct node {
node(T data, node* prev = nullptr, node* next = nullptr)
: data{ data }, prev{ prev }, next{ next } {}
T data;
node* prev;
node* next;
};
public:
struct iterator {
template <typename>
friend class list;
explicit iterator(node *_node = nullptr)
: _node(_node) {}
iterator& operator=(iterator const &it) {
_node = it._node;
return *this;
}
iterator& operator=(iterator &&it) …Run Code Online (Sandbox Code Playgroud) 在定义定制的析构函数时,C++标准委员会选择删除隐式定义的移动赋值运算符的理由是什么?
下面的代码给出了错误:
use of deleted function ‘constexpr B::B(const B&)’
Run Code Online (Sandbox Code Playgroud)
现在,我知道这是因为通过指定移动构造函数(有意)隐式删除了复制构造函数,并且复制向量会导致对(已删除)复制构造函数的调用.我想我也理解为什么使用向量的复制构造函数和赋值运算符.我显然想要使用移动构造函数和赋值运算符:移动对象,因此也移动它包含的向量.那么,如何让我的移动构造函数/赋值运算符使用向量的移动构造函数/赋值运算符?
这是代码:
#include <vector>
class B {
private:
/* something I don't want to copy */
public:
B() {};
B(B&& orig) {/* move contents */};
B& operator=(B&& rhs) {
/* move contents */
return *this;
};
};
class A {
private:
vector<B> vec;
public:
A() : vec() {};
A(A&& orig) : vec(orig.vec) {};
A& operator=(A&& rhs) {
vec = rhs.vec;
return *this;
};
};
Run Code Online (Sandbox Code Playgroud) 我创建了以下类来理解以下行为std::sort:
class X {
public:
X(int i) : i_(i) { }
X(X&& rhs) noexcept : i_(std::move(rhs.i_)) { mc_++; }
X& operator=(X&& rhs) noexcept {
i_ = std::move(rhs.i_); ao_++; return *this;
}
void swap(X& rhs) noexcept { std::swap(i_, rhs.i_); sw_++; }
friend bool operator<(const X& lhs, const X& rhs) {
return lhs.i_ < rhs.i_;
}
static void reset() { mc_ = ao_ = sw_ = 0; }
private:
int i_;
static size_t mc_, ao_, sw_; // function-call counters …Run Code Online (Sandbox Code Playgroud)