8

我想为我的类(我们称之为A)实现一个Swap()方法来制作复制和交换运算符=()。据我所知,swap方法应该通过交换类的所有成员来实现,例如:

class A 
{
  public:
    void swap(A& rhv) 
    {
        std::swap(x, rhv.x);
        std::swap(y, rhv.y);
        std::swap(z, rhv.z);
    }
  private:
    int x,y,z;
};

但是,如果我有一个 const 成员,我该怎么办?我不能为它调用std::swap,所以我不能编码A::Swap()。

编辑:其实我的课有点复杂。我想序列化和反序列化它。const 成员是该对象内不会更改的一段数据(例如其 ID)。所以我想写这样的东西:

class A
{
  public:
    void Serialize(FILE* file) const
    {
        fwrite(&read_a, 1, sizeof(read_a), file);
    }

    void Deserialize(FILE* file) const
    {
        size_t read_a;
        fread(&read_a, 1, sizeof(read_a), file);
        A tmp(read_a);
        this->Swap(tmp);
    }

 private:
   const size_t a;
};

并调用此代码:

A a;
FILE* f = fopen(...);
a.Deserialize(f);

我很抱歉这种含糊的措辞。

4

7 回答 7

10

我认为您真正想要的是拥有一个可以在对象之间轻松交换的内部数据结构。例如:

class A 
{
   private:

     struct A_Data {
       int x;
       int y;
       const int z;

       A_Data(int initial_z) : z(initial_z) {}
    };

    std::auto_ptr<A_Data> p_data;

  public:

     A(int initial_z) : p_data(new A_Data(initial_z)) {}

     void swap(A& rhv) {
        std::swap(p_data, rhv.p_data);
     }
};

这使对象内部数据z的任何实例中的值保持不变A,但您可以交换两个对象的内部数据A(包括常z量值),而不会违反 const 正确性。

于 2010-02-05T21:19:00.527 回答
5

睡个好觉后,我认为最好的答案是使用指向 const 值的非 const 指针——毕竟这些都是你试图捕捉的语义。

于 2010-02-06T12:11:56.637 回答
3

f0b0s,一个好的设计原则是将你的对象设计成不可变的。这意味着对象一旦创建就不能更改。要“更改”对象,您必须复制对象并确保更改所需的元素。

话虽如此,在这种情况下,您应该考虑使用复制构造函数来复制要交换的对象,然后实际交换对对象的引用。我可以理解仅仅能够在引擎盖下更改对象的元素是很诱人的,但是最好制作对象的副本并将对该对象的引用替换为NEW对象。这可以让你摆脱任何 const 的讨厌。

希望这可以帮助。

于 2010-02-05T21:20:27.560 回答
1

我建议您使用指向实例的指针。class与or中的数据相比,指针可以更容易地交换struct

交换常量值的唯一方法是创建另一个对象或clone当前对象。

给定一个结构:

struct My_Struct
{
  const unsigned int ID;
  std::string        name;
  My_Struct(unsigned int new_id)
    : ID(new_id)
  { ; }
};

我的理解是你想交换My_Struct上面类似的实例。您可以复制可变(非常量)成员,但不能复制const成员。更改const成员的唯一方法是为该成员创建一个具有新值的新实例const

也许您需要重新考虑您的设计。

于 2010-02-05T21:22:53.280 回答
0

这就是const_cast创建的原因。只要记住不要把你的脚踢掉。

编辑:好的,我承认 - const_cast 根本不是为这个问题而设计的。这可能适用于你的编译器,但你不能指望它,如果恶魔从你的鼻孔里飞出来,请不要怪我。

于 2010-02-05T21:06:39.600 回答
0

恕我直言,您必须考虑不要交换 CONST 成员。

PD:我认为你可以考虑在你的方法中使用反射。所以你不必维护这个功能。

于 2010-02-05T21:37:42.197 回答
0
于 2018-05-15T04:16:01.443 回答