C++11 字符串的作用是什么;我不干什么?c++;11 我对C++还很陌生,所以请容忍我。
我试图了解更多关于std::move的工作原理,我看到了一个示例,其中他们使用std::move将字符串移动到另一个函数,然后使用std::cout显示没有字符串保留。我觉得很酷,让我们看看我是否可以自己上课,也可以这样做:C++11 字符串的作用是什么;我不干什么?c++;11 我对C++还很陌生,所以请容忍我。,c++11,stdstring,C++11,Stdstring,我试图了解更多关于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})
#include <iostream>
#include <string>
class integer
{
private:
int *m_i;
public:
integer(int i=0) : m_i(new int{i})
{
std::cout << "Calling Constructor\n";
}
~integer()
{
if(m_i != nullptr) {
std::cout << "Deleting integer\n";
delete m_i;
m_i = nullptr;
}
}
integer(integer&& i) : m_i(nullptr) // move constructor
{
std::cout << "Move Constructor\n";
m_i = i.m_i;
i.m_i = nullptr;
}
integer(const integer& i) : m_i(new int) { // copy constructor
std::cout << "Copy Constructor\n";
*m_i = *(i.m_i);
}
//*
integer& operator=(integer&& i) { // move assignment
std::cout << "Move Assignment\n";
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 Assignment\n";
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 empty\n";
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 string\n";
g(std::move(s));
if(s.empty()) std::cout << "s is empty\n";
g(s);
std::cout << "\nNow for integer\n";
integer i = 77;
if(!i.empty()) std::cout << "i is " << i << '\n';
else std::cout << "i is empty\n";
g(i);
std::cout << "Move it\n";
g(std::move(i)); // rvalue ref called
if(!i.empty()) std::cout << "i is " << i << '\n';
else std::cout << "i is empty\n";
g(i);
return 0;
}
如您所见,它在第二次输入g时崩溃,甚至从未到达操作符您的“空整数”会崩溃程序,因为它包含空指针。当您在作业的右侧使用时,您正试图取消引用它
空字符串是正常的可用字符串。std::string
代码中没有未检查的空指针解引用
您必须确保对象的空状态是可用状态。从定义默认构造函数开始。这对你们班有意义吗?如果不是,那么移动语义也可能不是。如果是,则move构造函数中的moved from对象可能会与默认构造的对象处于相同的状态。移动分配可以充当交换操作,因此右侧可能最终为空或不空
如果您不想为类定义一个可用的空状态,并且仍然需要移动语义,那么您就不能在对象从中移动之后使用它。您仍然需要确保空对象是可销毁的。本练习的重点并不实用,而是要了解std::move是如何工作的。如何使空对象可销毁?析构函数不应崩溃或有其他不希望的行为。这取决于析构函数的作用,但基本上,如果有一个指针要
delete
,指针必须指向一个对象,该对象可以是delete
d,也可以是nullptr
。你班上已经有了。请注意另一个bug,有时调用newint
,有时调用newint[1]
。这是非法的。我修复了“new int/new int[1]”问题(谢谢,请参见上文)。我已经确定程序在调用std::cout之前崩溃,因此使用空整数调用g的行为与使用空std::string调用g的行为有所不同。我还是缺少一些东西。对不起,说得太多了,我已经解释过了。您的空整数有一个空指针。您的访问函数在不进行检查的情况下取消对指针的引用。这在C++中是不允许的。您需要确定空整数是否为有效对象。尚不清楚空整数将具有什么语义。一个空整数加2等于多少?打印一个空整数意味着什么?你需要把它想清楚,写下来并实施它。空字符串有效,并且具有定义良好的seantics。手动移动构造函数通常使用std::move
移动成员。感谢您的帮助,解决了此问题。如果我理解的话,就是在move构造函数(和赋值操作符)中,我将I.m_I视为左值而不是右值。是这样吗?
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.