标签: copy-and-swap

如何交换 MFC CString?

好的,所以我完全接受了复制和交换习语,我想我主要知道如何实现它。

但是,或者代码库使用MFC 的 CString 类作为字符串,这不会改变。

既然swap必须(应该???)不抛出,我不能

std::swap(this->my_cstring, rhs.my_cstring);
Run Code Online (Sandbox Code Playgroud)

因为这将创建一个可能抛出的临时 CString 对象。(加上它的低效。)

那么我还剩下什么?我应该添加一个try-catch吗?我真的应该允许这种(好吧,非常罕见)内存不足的情况引发异常并使交换失败?

查看 CStrings 实现,似乎没有允许交换的成员或函数......

mfc swap cstring visual-c++ copy-and-swap

5
推荐指数
1
解决办法
1377
查看次数

模板类的友元函数中的链接错误

我有模板类节点,为了遵循复制和交换习惯用法,我尝试编写swap属于friend类的函数Node

我的代码是:

Node.h

#ifndef NODE_H
#define NODE_H

#include<memory>
template<typename type>
class Node
{
    type data_;
    std::unique_ptr<Node> next_;
public:
    Node(type data);
    Node(const Node& other);
    Node& operator=(Node other);
    friend void swap(Node& lhs, Node& rhs);
};

#include "Node.tpp"
#endif
Run Code Online (Sandbox Code Playgroud)

Node.tpp

template<typename type>
Node<type>::Node(type data):data_(data),next_(nullptr){
}

template<typename type>
Node<type>::Node(const Node& other)
{
    data_ = other.data_;
    next_ = nullptr;
    if(other.next_ != nullptr)
    {
        next_.reset(new Node(other.next_->data_));
    }
}
template<typename type>
void swap(Node<type>& lhs, Node<type>& rhs)
{
    using std::swap; …
Run Code Online (Sandbox Code Playgroud)

c++ copy-and-swap

5
推荐指数
1
解决办法
403
查看次数

在虚拟继承中交换和复制习惯用法的正确方法是什么?

考虑经典的虚拟继承钻石层次结构.我想知道在这种层次结构中复制和交换习语的正确实现是什么.

这个例子有点人为 - 并且它不是很聪明 - 因为它可以很好地使用A,B,D类的默认复制语义.但只是为了说明问题 - 请忘记示例弱点并提供解决方案.

所以我从两个基类(B <1>,B <2>)派生出D类 - 每个B类几乎从A类继承.每个类都有非平凡的复制语义,使用复制和交换习语.派生最多的D类在使用这个习语时有问题.当它调用B <1>和B <2>交换方法时 - 它将虚拟基类成员交换两次 - 所以一个子对象保持不变!

A:

class A {
public:
  A(const char* s) : s(s) {}
  A(const A& o) : s(o.s) {}
  A& operator = (A o)
  {
     swap(o);
     return *this;
  }
  virtual ~A() {}
  void swap(A& o)
  {
     s.swap(o.s);
  }
  friend std::ostream& operator << (std::ostream& os, const A& a) { return os << a.s; }

private:
  S s;
};
Run Code Online (Sandbox Code Playgroud)

template <int N> …
Run Code Online (Sandbox Code Playgroud)

c++ multiple-inheritance virtual-inheritance diamond-problem copy-and-swap

4
推荐指数
1
解决办法
2210
查看次数

使用swap实现移动分配

在我身上发生了一些我认为完全合理的事情,但是我想要人们对它的看法,以防我完全遗漏某些东西.首先,我的理解T& operator=(T&& rhs)是,当我们完成时,我们不关心内容rhs是什么,只是内容已被移入this并且rhs可以安全地破坏.

话虽这么说,假设交换很便宜,复制赋值运算符的常见异常安全实现看起来像这样:

T& operator=(const T& rhs) {
    if(this != &rhs) {
        T(rhs).swap(*this);
    }
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

因此,实现移动赋值运算符的一种自然方式是这样的:

T& operator=(T&& rhs) {
    if(this != &rhs) {
        T(std::move(rhs)).swap(*this);
    }
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

但它发生在我身上,rhs不一定是空的!那么,为什么不做一个平原swap呢?

T& operator=(T&& rhs) {
    rhs.swap(*this); // is this good enough?
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

认为这满足了移动赋值操作符需要做的...但就像我说的那样,这只是发生在我身上,所以我认为我可能会遗漏一些东西.

我能想到的唯一"缺点"是,this与执行move-construct/swap的版本相比,拥有的东西使用普通交换可能会延长寿命.

思考?

c++ copy-and-swap c++11 move-assignment-operator

4
推荐指数
1
解决办法
1628
查看次数

在副本和交换习语中实现交换

下面什么是复制和交换习惯用法以及如何为我的班级提供交换功能,我尝试实现交换功能,如后面接受的答案选项2(具有调用成员函数的自由函数)而不是直接友好前链接中的自由功能.

但是以下不编译

#include <iostream>

// Uncommenting the following two lines won't change the state of affairs
// class Bar;
// void swap(Bar &, Bar &);
class Bar {
public:
  Bar(unsigned int bottles=0) : bottles(bottles) { enforce(); } // (1)
  Bar(Bar const & b) : bottles(b.bottles) { enforce(); } // (1)

  Bar & operator=(Bar const & b) {
    // bottles = b.bottles;
    // enforce();
    // Copy and swap idiom (maybe overkill in this example)
    Bar tmp(b); // …
Run Code Online (Sandbox Code Playgroud)

c++ copy-constructor assignment-operator copy-and-swap c++11

4
推荐指数
1
解决办法
647
查看次数

类的复制和交换习惯用法,引用抽象类

我正在尝试为我的类实现Copy-and-Swap Idiom,因为我需要实现operator=,因为它有引用成员,并且引用只能分配一次,我认为前面提到的成语是一个有效的解决方法.

但现在我收到了一个构建错误:

>c:\Program Files\Microsoft Visual Studio 10.0\VC\include\utility(102): error C2259: 'IVariables' : cannot instantiate abstract class
1>          due to following members:
1>          'IVariables::~IVariables(void)' : is abstract
1>          d:\svn.dra.workingcopy\serialport\IVariables.h(6) : see declaration of 'IVariables::~IVariables'
1>          'std::string &IVariables::operator [](const std::string &)' : is abstract
1>          d:\svn.dra.workingcopy\serialport\IVariables.h(7) : see declaration of 'IVariables::operator []'
1>          'unsigned int IVariables::getVariableLength(const std::string &) const' : is abstract
1>          d:\svn.dra.workingcopy\serialport\IVariables.h(8) : see declaration of 'IVariables::getVariableLength'
1>          Message.cpp(32) : see reference to function template instantiation …
Run Code Online (Sandbox Code Playgroud)

c++ abstract-class reference copy-and-swap

2
推荐指数
1
解决办法
691
查看次数

copy-swap idom:如果我改变了班级成员怎么办?

我上课了

class MyClass
{
public :
 int a;
 int b;
}
Run Code Online (Sandbox Code Playgroud)

为了使用copy-swap惯用语,我创建了该函数

void MyClass::swap(MyClass& other)
{
   std::swap(a,other.a);
   std::swap(b,other.b);
}
Run Code Online (Sandbox Code Playgroud)

如果,稍后,我更改了我的类并删除了该成员a,那么编译器会在swap函数中抱怨,这没关系.

但是如果我添加一个新成员,我的swap功能就不再正确了.为了不忘记将新成员添加到交换功能,我该怎么办?

c++ copy-and-swap

2
推荐指数
1
解决办法
81
查看次数

`std::swap` 在应用于这些对象时有什么作用?

编码

using namespace std;

class A 
{
private:
  vector<int> a;
public:
  A(vector<int> x):a(x){}
  string toString()
  {
      string s;
      for (auto& element : a)
      {
          s += to_string(element) + " ";
      }
      return s;
  }
};

int main()
{
    A a1({1,2,3});
    A a2({11,12,13});

    cout << "a1 = " << a1.toString() << "\n";
    cout << "a2 = " << a2.toString() << "\n";
    
    swap(a1,a2);
    
    cout << "a1 = " << a1.toString() << "\n";
    cout << "a2 = " << a2.toString() << "\n";
    
    return …
Run Code Online (Sandbox Code Playgroud)

c++ arrays swap copy-and-swap

2
推荐指数
1
解决办法
730
查看次数