我一直在编写自己的 String 类,考虑到我可以将右值传递给它,我不确定如何正确编写 operator+。我认为我应该具有以下 3 个非成员函数
String operator+(String &&lhs, String &&rhs);
String operator+(String& lhs,String&&rhs);
String operator+(String&&lhs,String&rhs);
但是我不确定如何实现它们。任何帮助将不胜感激。
最佳答案
首先,确保在 String
中定义复制和移动构造函数类:
class String
{
private:
char *m_data;
std::size_t m_length;
...
public:
String();
String(const String &src);
String(String &&src);
~String();
...
};
String::String() :
m_data(nullptr),
m_length(0)
{
}
String(const String &src) :
m_data(new char[src.m_length+1]),
m_length(src.m_length)
{
std::copy_n(src.m_data, m_length, m_data);
m_data[m_length] = 0;
}
String(String &&src) :
m_data(nullptr),
m_length(0)
{
std::swap(m_data, src.m_data);
std::swap(m_length, src.m_length);
}
String::~String()
{
delete[] m_data;
}
然后定义operator+
和 operator+=
对于类(class):
class String
{
public:
...
String& operator+=(const String &rhs);
...
friend String operator+(String lhs, const String &rhs)
{
lhs += rhs;
return lhs;
}
};
String& String::operator+=(const String &rhs)
{
String tmp;
tmp.m_length = m_length + rhs.m_length;
tmp.m_data = new char[tmp.m_length+1];
std:copy_n(m_data, m_length, tmp.m_data);
std:copy_n(rhs.m_data, rhs.m_length, tmp.m_data + m_length);
tmp.m_data[tmp.m_length] = 0;
std::swap(m_data, tmp.m_data);
std::swap(m_length, tmp.m_length);
return *this;
}
通过 const String &
作为右侧的输入,它将处理左值和右值输入。
对于 operator+
,左侧按值取值,因此编译器可以根据输入是左值(复制)还是右值(移动)来决定要使用的最佳构造函数。
或者,您可以实现它以获取 const String &
在左侧,所以它仍然处理左值和右值,但是你必须像operator+=
那样实现它实现是为了避免复制的额外分配lhs
在连接到它之前:
friend String operator+(const String &lhs, const String &rhs)
{
/*
String tmp(lhs);
tmp += rhs;
return tmp;
*/
String tmp;
tmp.m_length = lhs.m_length + rhs.m_length;
tmp.m_data = new char[tmp.m_length+1];
std:copy_n(lhs.m_data, lhs.m_length, tmp.m_data);
std:copy_n(rhs.m_data, rhs.m_length, tmp.m_data + lhs.m_length);
tmp.m_data[tmp.m_length] = 0;
return tmp;
}
无论哪种方式,您还应该定义一个转换构造函数和operator+
对于 const char *
也输入:
class String
{
public:
...
String(const char *src);
...
friend String operator+(const char *lhs, const String &rhs)
{
return String(lhs) + rhs;
/* or:
std::size_t len = std::strlen(lhs);
String tmp;
tmp.m_length = len + rhs.m_length;
tmp.m_data = new char[tmp.m_length+1];
std:copy_n(lhs, len, tmp.m_data);
std:copy_n(rhs.m_data, rhs.m_length, tmp.m_data + len);
tmp.m_data[tmp.m_length] = 0;
return tmp;
*/
}
...
};
String::String(const char *src) :
m_data(nullptr),
m_length(std::strlen(src))
{
m_data = new char[m_length+1];
std::copy_n(src, m_length, m_data);
m_data[m_length] = 0;
}
这将允许连接 String
具有字符串文字的对象( String + "literal"
、 "literal" + String
、 String += "literal"
等)。
参见 operator overloading在 cppreference.com了解更多详情。
关于c++ - 使用右值编写 operator+ 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46834880/