我试图了解实现复制赋值运算符的正确方法=
。所以我实现了这个例子:
class Window {
public:
Window(const std::string& = std::string());
Window(const Window&);
Window& operator=(const Window&);
~Window();
std::string win_name()const { return *psWinName; }
std::size_t win_id()const { return winID; }
private:
std::string* psWinName = nullptr;
std::size_t winID;
};
Window::Window(const std::string& win_name) :
psWinName(new std::string(win_name)),
winID(0) {
}
Window::Window(const Window& rhs) :
psWinName(new std::string(*rhs.psWinName)),
winID(rhs.winID) {
}
/* Erroneous copy-assignment operator
Window& Window::operator=(const Window& rhs)
{
delete psWinName;
psWinName = new std::string(*rhs.psWinName);;
winID = rhs.winID;
return *this;
}
*/
Window& Window::operator=(const Window& rhs)
{
std::string* tmp = new std::string(*rhs.psWinName);
delete psWinName;
psWinName = tmp;
winID = rhs.winID;
return *this;
}
Window::~Window()
{
delete psWinName;
}
int main()
{
/*Window win_explorer("Explorer");
auto win_exp2(win_explorer);
Window win_desktop("Desktop Window");
Window win;
win = win_desktop;
win = win;
cout << win_explorer.win_name() << " : " << win_explorer.win_id() << endl;
cout << win_exp2.win_name() << " : " << win_exp2.win_id() << endl;
cout << win_desktop.win_name() << " : " << win_desktop.win_id() << endl;
cout << win.win_name() << " : " << win.win_id() << endl;*/
int* p = new int(9);
cout << p << " " << *p << endl;
int* tmp = p;
cout << tmp << " " << *tmp << endl;
delete p;
p = new int(*tmp);
cout << p << " " << *p << endl;
cout << tmp << " " << *tmp << endl;
cout << "\ndone\n";
}
到目前为止,我已经展示了不正确的=
运算符形式。
是不是错了,因为:
delete psName;
psName = new std::string(*rhs.psName); // UB here?
所以我不知道这里的评估顺序是如何发生的:
psName = new std::string(*rhs.psName);
. 那么这是一个UB吗?还有呢:
delete psName; psName = new std::string(); *psName = *rhs.psName;
但是会产生相同的结果,即未定义的值。
- 我谈论将一些对象分配给自身。
** 人们也争论:delete psName; psName = new std::string();
他们说new
可能会扔。但我认为只要我发布了与它相同的资源,它就不应该。
** 注意:事实上,我不是关于std::string
获取任何资源,而是关于获取任何资源。