0

首先,我认为我想要的术语既不是“延迟加载”也不是“动态绑定”。我不知道正确的术语,但是当我这样做时我会编辑这个问题。延迟加载/动态绑定vs安全

我连接处理对象来创建数据流A-> B:

方法1:实例化过程中连接 代码:https://ideone.com/Rsqabi

class Consumer { 
public: 
    virtual void consume(int data) = 0; 
}; 

class A { 
public: 
    A(Consumer& consumer) : consumer_(consumer) {} 
    void process(int data) { consumer_.consume(data); } 
private: 
    Consumer& consumer_; 
}; 

class B : public Consumer { 
public: 
    B() {} 
    void consume(int data) { /* consume data */ } 
}; 

我必须有一个消费者实例方便实例化 - 答:

int main() { 
    B* b_ = new B(); 
    A a_ = A(*b_); 
    a_.process(5); 
    return 0; 
} 

方法2:连接后实例化 代码:https://ideone.com/5ij0yZ

我真正想要的是选择我的消费类实例化后:

class A { 
public: 
    A() {} 
    void attachConsumer(Consumer* consumer) { consumer_ = consumer; } 
    void process(int data) { 
     // must always check consumer_ here! 
     consumer_->consume(data); 
    } 
private: 
    Consumer* consumer_; 
}; 

然后:

int main() { 
    A a_ = A(); 
    // ... for reasons I won't tell you, B must be created later than A ... 
    B* b_ = new B(); 
    a_.attachConsumer(b_); 
    a_.process(5); 
    return 0; 
} 

更好的模式?

方法1是伟大的,因为我总是知道参考是有效的。这是不灵活的,这很糟糕。

方法2很好,因为我可以选择消费者附加的道路(或者如果安全地考虑状态,则重新附加)。这很糟糕,因为指针是危险的。

是否有方法3满足两个模型的正数?在哪里我不总是需要检查我的消费者是否有效并附加,但是这也允许动态连接?

这些模型的区别是什么?我不认为这是懒加载或动态绑定。请指教。

回答

0

方法1导致内存泄漏,因为必须删除消费者A后才会删除。引用是有效的,但它不会在被销毁时销毁对象,因此您仍然需要“记住”释放B,从而消除了第一种方法的优点。

使用std :: shared_ptr来保存B,如果你害怕忘记释放B,并且想确保持有它。

不要忘记添加“显式”的构造函数与一个参数。