强制c++类实例在复制或赋值时更改成员值

Force C++ class instances to change member value when copied or assigned

本文关键字:成员 赋值 c++ 实例 复制 强制      更新时间:2023-10-16

我有一个名为Solution的类定义如下。我只包含了相关的代码,并且我已经而不是编写了自定义复制或赋值操作符。

class Solution {
public:
    Solution() {
        stream.setNewSeed(seedShift+static_cast<long>(12345));
        ++seedShift;
    }
    RandomNumberStream stream;
private:
    static long seedShift = 0;
};

这里的要点是,我希望Solution的每个新实例具有不同的随机数流。这工作。

问题是,然而,有一些地方我从std::vector<Solution>复制Solution的实例,稍微修改它,然后将副本推到相同的std::vector<Solution>上。当这种情况发生时,我有两个具有相同随机数seed的Solution实例,灾难随之而来。

我怎样才能使stream.setNewSeed(seedShift+static_cast<long>(12345));++seedShift;语句在被推到矢量上的复制Solution实例中运行?

重载赋值操作符。注意——这也意味着当你从vector中读取值和/或复制vector本身时,随机数seed也会再次改变。

class Solution {
public:
    Solution() {
        stream.setNewSeed(seedShift+static_cast<long>(12345));
        ++seedShift;
    }
    Solution& operator=(Solution& other)
    {
        stream.setNewSeed(seedShift+static_cast<long>(12345));
        ++seedShift;

        x = other.x;
        y = other.y;
        z = other.z;

        return *this;
    }
    RandomNumberStream stream;
private:
    static long seedShift = 0;
};

压入vector将使用复制构造函数(或移动构造函数,但我们将使其简单,并假设它现在使用复制构造函数)。它具有签名:

Solution(const Solution& rhs);

然后您可以相当简单地实现此逻辑:

Solution(const Solution& rhs)
{ 
     stream.setNewSeed(seedShift + 12345L);
     ++seedShift;
}

注意,如果你实现了这个,你可能也应该实现复制赋值操作符:

Solution& operator=(const Solution& rhs)
{
    if(this != &rhs) {
        stream.setNewSeed(seedShift+static_cast<long>(12345));
        ++seedShift;
    }
    return *this;
}