我还是C++的新手,所以请耐心等待。
我试图了解更多关于std::move如何工作的信息,我看到了一个例子,他们使用std::move将字符串移动到不同的函数,然后使用std::cout显示没有字符串。我觉得很酷,让我们看看我是否可以制作自己的课程并做同样的事情:
#include <iostream>
#include <string>
class integer
{
private:
int *m_i;
public:
integer(int i=0) : m_i(new int{i})
{
std::cout << "Calling Constructorn";
}
~integer()
{
if(m_i != nullptr) {
std::cout << "Deleting integern";
delete m_i;
m_i = nullptr;
}
}
integer(integer&& i) : m_i(nullptr) // move constructor
{
std::cout << "Move Constructorn";
m_i = i.m_i;
i.m_i = nullptr;
}
integer(const integer& i) : m_i(new int) { // copy constructor
std::cout << "Copy Constructorn";
*m_i = *(i.m_i);
}
//*
integer& operator=(integer&& i) { // move assignment
std::cout << "Move Assignmentn";
if(&i != this) {
delete m_i;
m_i = i.m_i;
i.m_i = nullptr;
}
return *this;
}
integer& operator=(const integer &i) { // copy assignment
std::cout << "Copy Assignmentn";
if(&i != this) {
m_i = new int;
*m_i = *(i.m_i);
}
return *this;
}
int& operator*() const { return *m_i; }
int* operator->() const { return m_i; }
bool empty() const noexcept {
if(m_i == nullptr) return true;
return false;
}
friend std::ostream& operator<<(std::ostream &out, const integer i) {
if(i.empty()) {
std::cout << "During overload, i is emptyn";
return out;
}
out << *(i.m_i);
return out;
}
};
void g(integer i) { std::cout << "G-wiz - "; std::cout << "The g value is " << i << 'n'; }
void g(std::string s) { std::cout << "The g value is " << s << 'n'; }
int main()
{
std::string s("Hello");
std::cout << "Now for stringn";
g(std::move(s));
if(s.empty()) std::cout << "s is emptyn";
g(s);
std::cout << "nNow for integern";
integer i = 77;
if(!i.empty()) std::cout << "i is " << i << 'n';
else std::cout << "i is emptyn";
g(i);
std::cout << "Move itn";
g(std::move(i)); // rvalue ref called
if(!i.empty()) std::cout << "i is " << i << 'n';
else std::cout << "i is emptyn";
g(i);
return 0;
}
这是我的输出:
Now for string
The g value is Hello
s is empty
The g value is
Now for integer
Calling Constructor
Copy Constructor
i is 77
Deleting integer
Copy Constructor
G-wiz - Copy Constructor
The g value is 77
Deleting integer
Deleting integer
Move it
Move Constructor
G-wiz - Copy Constructor
The g value is 77
Deleting integer
Deleting integer
i is empty
Copy Constructor
Process returned 255 (0xFF) execution time : 7.633 s
Press any key to continue.
如您所见,当它第二次进入 g 时它会崩溃,甚至从未进入运算符<<(( 函数。空的 std::string s 是如何传递给 g 的,我的空整数 i 使程序崩溃?
编辑:修复了新 int 与新 int[] 错误。谢谢 n.m.
您的"空整数"使程序崩溃,因为它包含一个空指针。当您在作业的右侧使用它时,您正在尝试取消引用它。
空字符串是正常的可用字符串。std::string
代码中没有未经检查的空指针取消引用。
您必须确保对象的空状态是可用的状态。从定义默认构造函数开始。这对你的班级有意义吗?如果不是,那么移动语义可能也不会。如果是,则移动构造函数中的移自对象可能最终应与默认构造对象处于相同的状态。移动分配可以充当交换操作,因此右侧可能最终为空或不为空。
如果您不想为类定义可用的空状态,并且仍然需要移动语义,则在移动对象后,您根本无法使用该对象。您仍然需要确保空对象是可破坏的。