是否可以在c ++中返回交换,而不是按值返回?

时间:2016-08-24 04:25:07

标签: c++ string pointers swap

假设我正在用C ++编写一个字符串类(我知道我可以使用该库)。字符串长度是可变的,存储空间在构造函数中动态分配,并在析构函数中释放。当main函数调用c=a+ba,b,c是字符串)时,operator+成员函数会创建一个临时对象,用于存储连接字符串a+b,并将其返回给main函数,然后调用operator=成员函数来释放最初存储在c中的字符串,并将数据从临时字符串a+b复制到c ,最后,临时a+b被破坏。

我想知道是否有办法实现这一目标:我希望它交换operator=a+b的{​​{1}}副本数据,而不是c复制数据。 {1}}和a+b,以便在c被解构时,它会导致a+b中的原始数据(这是我们想要的),而c现在需要c的结果,无需复制。

我知道编写一个双参数成员函数a+b,调用setToStrcat可以做到这一点。例如,函数可以编码为:

c.setToStrcat(a,b)

我省略了构造函数的定义(分配 void String::setToStrcat(const String& a,const String& b){ String tmp(a.len+b.len); int i,j; for(i=0;i<a.len;i++) tmp[i]=a[i]; for(j=0;j<b.len;i++,j++) tmp[i]=b[j]; tmp[i]='\0'; this->swap(tmp); } void String::swap(String& a){ int n=len; len=a.len; a.len=n; char *s=str; str=a.str; a.str=s; } char-type空格)和len+1(返回operator[]字符的引用)。 i函数在swap*this之间交换数据指针和长度变量,以便在交换后解析tmp时,它实际上是最初存储在tmp中的数据被破坏的{1}}(*this函数中的String c)。 main现在拥有的内容(*this)是连接字符串c.str

我想知道是否有办法将a+b的性能优化到同一级别。我尝试c=a+b并将c.swap(a+b)的返回类型更改为a+b,但我收到警告(引用局部变量),GDB显示临时在交换发生之前被破坏,而我想要另一种方式。

我认为我的问题很笼统。在C ++编程中,我们经常需要一个临时对象来存储函数的结果,但是当我们将它分配给main函数中的另一个对象时,我们可以不复制数据而是使用(更快)交换指针吗?什么是实现这一目标的巧妙方法?

1 个答案:

答案 0 :(得分:1)

在C ++ 11中,您可以通过编写移动构造函数来完成此操作。 Rvalue引用被添加到语言中以解决这个确切的问题。

class String {
  ...
  String(String&& s) : str(nullptr) {
    this->swap(s);
  }
  String& operator=(String&& s) {
    this->swap(s);
  }
  ...
  String operator+(String const& other) {
    // (your implementation of concatenation here)
  }
  ...
}

然后像这样的代码不会触发额外的复制构造函数或内存分配,它只会将分配的内存从临时(从operator +返回的东西)移动到新对象c

String c = a + b;