一个对象可以警告一个类在c ++中已经改变了吗?

时间:2013-06-16 21:46:27

标签: c++

Class1可以警告Class2它已经改变而我不必创建一个方法来访问Class2中的Class1对象吗?基本上我想坚持点符号..没有二传手和吸气剂。

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存在吗?

1 个答案:

答案 0 :(得分:2)

根据评论中的建议,您可以应用Observer pattern来完成此操作。一种简单的方法是提供一个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");
}