在c++中,对象可以警告类它已经发生了变化吗?

can an object warn a class that it has changed in c++?

本文关键字:发生了 变化 警告 c++ 对象      更新时间:2023-10-16

Class1可以警告Class2它已经改变,而不需要我创建一个方法来访问Class2中的Class1对象吗?基本上我想坚持使用点符号。没有setter和getter

class Class1 {
public:
    void operator=(Class1 class1Obj) {
        // call class1ObjWasChanged() which is in Class2 from here
    }
};
class Class2 {
public:
    Class1 class1Obj;
    void class1ObjWasChanged() {
        std::cout << "class1Obj was changed!!";
    }
};

int main() {
    Class2 class2Obj;
    Class1 someClass1Obj;
    class2Obj.class1Obj = someClass1Obj;
}
如果可能的话,上面的代码应该以某种方式调用class1ObjWasChanged()。难道Class1不知道Class2的存在吗?

正如评论中建议的那样,您可以应用观察者模式来完成此操作。实现这一点的一个简单方法是提供一个Observer类,该类定义一个或多个纯虚函数,这些函数将在发生更改时调用。然后,您将需要维护一个对象列表,这些对象希望收到更改通知。在你把这些放在一起之后,你可以在你的拷贝赋值操作符中添加必要的逻辑来调用所有请求更改通知的对象。

#include <vector>
#include <iostream>
#include <string>
class Observable
{
public:
    // Provide class that defines the requirements of an observer class
    // that is capable of receiving change notifications.
    struct Observer
    {
        virtual ~Observer() {}
        // Pure virtual function requires all derived classes to
        // provide an implementation of the function.
        virtual void onChanged(const Observable& object) = 0;
    };
    // constructor
    Observable(const std::string& name) : name_(name) {}
    // Let the outside world add observers that will be notified.
    void addObserver(Observer* ob)
    {
        observers_.push_back(ob);
    }
    // copy assignment operator
    Observable& operator=(const Observable& other) 
    {
        name_ = other.name_;
        // alert the observers that want to know about changes
        for(auto it = observers_.begin(); it != observers_.end(); ++it)
        {
            (*it)->onChanged(*this);
        }
        return *this;
    }
    std::string name() const
    {
        return name_;
    }
private:
    std::string name_;
    std::vector<Observer*>  observers_;
};

class PeepingTom : public Observable::Observer
{
public:
    void onChanged(const Observable& object)
    {
        std::cout
            << "object name was changed to '"
            << object.name()
            << "'"
            << std::endl;
    }
};

int main()
{
    PeepingTom  observer;
    Observable  changable("some name");
    // Add the observer
    changable.addObserver(&observer);
    std::cout
        << "`changable` is currently name named '"
        << changable.name()
        << "'"
        << std::endl;
    // Change it
    changable = Observable("new name");
}