C++陷入相等运算符分配的无限循环

标签 c++

我发现自己陷入了一种 hell 般的噩梦,我试图使用 equals 运算符重新分配一个通过另一个内部对象引用自身的对象。
这个设计的目标是

  • 创建一个名为 Foo 的对象
  • 创建一个名为 FooEventHandler 的内部对象包含对 Foo 的引用
  • FooEventHandler转至 EventEmitter这样它就可以调用Foo事件函数

  • 我提供了最少量的代码来同时说明目标和问题。我的 Event 没有任何问题迄今为止的模块,包括我的扩展范式 EventHandler s 引用它们的父对象(在本例中为 Foo)并被发送到 EventEmitter这样它就可以调用任何Foo函数,有点像 lambda 函数的实现。
    然而,在使用这个设计大约一年之后,当我需要做一些类似 foo1 = foo2 的事情时,我遇到了一个主要障碍。 (= 运算符)或 Foo foo1 = foo2 (复制构造函数)。我遇到了引用不可分配的问题( FooEventHandlerFoo 的引用)。所以我试图通过编写手动复制 ctor 和 = 来解决这个问题。运算符,现在我陷入了 = 的无限循环运算符(operator)。
    当我挖掘这个时,我什至不知道我想要完成什么,更不用说如何解决它了。 = 的目的之一当我想更新 Foo只需用新的 Foo 替换它即可对象,例如 foo1 = foo2 .但是,我正在转动我的轮子,试图弄清楚我想用 Foo 做什么的EventHandler . foo1EventHandler应该仍然引用自己,所以也许在 =运算符我不会重新分配 EventHandler .. 但是,也许我这样做是因为 foo1应该是 =foo2谁的EventHandler引用资料 foo2 !.. 或者可能不是.. 或者可能是??!
    我希望有人可以看看这个问题,让我清楚我应该做什么。
    注意:我在 c++ 98
    #include <iostream>
    #include <string>
    #include <vector>
    
    // EventHandler and EventEmitter are just included to display my intent 
    class EventHandler {
        public:
            virtual ~EventHandler(){}  
            virtual void HandleEvent(/*some event*/) = 0;
    };
    
    class EventEmitter {
        public:
            std::vector<EventHandler*> handlers;
            void AddHandler(EventHandler *handler){
                this->handlers.push_back(handler);
            }
            void EmitEvent(/*some event*/){
                for(size_t i = 0; i < this->handlers.size(); i++){
                    this->handlers.at(i)->HandleEvent(/*some event*/);
                }
            }
    };
    
    // The problem arises in Foo/FooEventHandler with circular references
    class Foo {
        public:
            
            // This object is designed to carry Foo to the EventEmitter
            class FooEventHandler : public EventHandler {
                public:
                    Foo &foo;
                    FooEventHandler(Foo &foo)
                        :EventHandler(),
                         foo(foo)
                    {
                        printf("FooEventHandler CONSTRUCTOR\n");   
                    }
                    FooEventHandler(const FooEventHandler &event_handler)
                        :EventHandler(),
                         foo(event_handler.foo)
                    {
                        printf("FooEventHandler COPY\n");   
                    }
                    FooEventHandler operator=(const FooEventHandler& event_handler) {
                        printf("FooEventHandler =\n");   
                        this->foo = event_handler.foo;
                    }
                    ~FooEventHandler(){
                        printf("FooEventHandler DESTRUCTOR\n");   
                    }
                    void HandleEvent(/*some event*/){
                        this->foo.HandleSomeEvent();
                    }
                    
            };
        
            // Foo is just some generic object with a custom handler to ref itself 
            FooEventHandler event_handler;
            Foo(std::string name)
                :event_handler(*this)
            {
                printf("Foo CONSTRUCTOR\n");   
            }
            Foo(const Foo &foo)
                :event_handler(foo.event_handler)
            {
                printf("Foo COPY\n"); 
            }
            Foo operator=(const Foo& foo)
            {
                printf("Foo =\n");    
                this->event_handler = foo.event_handler;
            }
            ~Foo(){
                printf("Foo DESTRUCTOR\n");   
            }
            void HandleSomeEvent(/*some event*/){
                printf("Look at me handling an event");
            }
    };
    
    int main()
    {
        printf("Foo1 create\n");
        Foo foo1("a");
    
        printf("Foo2 equal\n");
        Foo foo2("b");
        // start infinite loop of ='s
        foo2 = foo1;
    }
    

    最佳答案

    这是无限循环。这些函数相互调用。

    Foo(const Foo &foo)        :event_handler(foo.event_handler)
        {
            printf("Foo COPY\n"); 
        }
    
    FooEventHandler(const FooEventHandler &event_handler)
                    :EventHandler(),
                     foo(event_handler.foo)
                {
                    printf("FooEventHandler COPY\n");   
                }
    
    我认为 FooEventHandler 不应该从抽象方面引用 Foo 。你应该改变你的设计。

    关于C++陷入相等运算符分配的无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63400682/

    相关文章:

    c++ - 是否可以使函数对常量参数或变量参数表现不同?

    python - Swig C++ python 包装器文件解释?

    c++ - C++ 中的正则表达式跳过

    c++ - 在共享内存中分配对象

    c++ - 在 C++ 中解析设备文件的 ASCII 输出

    c++ - 如何启动内存有限的进程?

    c++ - 1 2 3 4 的组合

    c++ - 更快地读取带有 float 的文本文件并存储在浮点 vector 中

    c++ - 如何在 Bazel 中静态链接系统库?

    c++ - 我可以设置 array[n+k] = array[0] 吗?