gpt4 book ai didi

c++ - "Observer pattern"上的复制构造函数

转载 作者:行者123 更新时间:2023-12-01 01:40:32 25 4
gpt4 key购买 nike

假设我们有一个类似于这个的设计模式:

#include <set>

class Receiver;

class Transmitter {
public:
Transmitter() = default;

virtual ~Transmitter() {
for(auto recv : m_receivers){
recv->setSource(nullptr);
}
}

const std::set<Receiver*> getReceivers(){
return m_receivers;
}
private:
std::set<Receiver*> m_receivers;
};

class Receiver {
public:
Receiver() = default;
Receiver(const Receiver& other){
setTransmitter(other.m_trans);
}
~virtual ~Receiver(){
setTransmitter(nullptr);
}

void setTransmitter(Transmitter* tr){
if(m_trans) m_trans->m_recv.erase(this)
m_trans=tr;
if(m_trans) m_trans->m_recv.insert(this)
}
private:
Transmitter* m_trans = nullptr;
};
好像是 Observer pattern : 两个类的关系为 1:M 并且都持有彼此的引用。
现在想象我们想让它们与 std::vector 兼容。或任何其他类似的 std容器。因此它需要是可复制构造的(或可移动的)。 Receiver可以复制(如上面的代码所示),但是,问题出现在发射器上。我想过不同的选择,但我无法决定该怎么做:
  • 复制构造函数应该作为默认构造函数还是应该删除?
  • 我应该定义一个从另一个窃取接收者的移动构造函数吗?
  • 或者我应该简单地禁止复制和移动初始化? (没有解决问题的方法)
    有一个similar question in stack overflow about this problem in Java .然而,C++ 的答案可能会改变
  • 最佳答案

    移动构造函数将是合适的:

    Transmitter(Transmitter&& other) noexcept : m_receivers(std::move(other.m_receivers)) {
    for (auto recv : m_receivers) {
    recv->m_trans = this;
    }
    }

    移动之所以有效,是因为在移动之后,新对象应该等同于被移动的对象,所以从观察者的角度来看,发射器没有改变。

    这与 Java 不同的原因是 Java 没有移动构造函数,因此没有(简单的)方法来表达“窃取观察者/资源”。

    关于c++ - "Observer pattern"上的复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58222961/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com