延迟加载/动态绑定与安全性

时间:2014-03-31 17:56:09

标签: c++ design-patterns software-design dynamically-generated

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

我正在连接处理对象以创建数据流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 */ }
};

我必须有一个Consumer实例,以便实例化A:

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

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

我真正想要的是在实例化A:

后选择我的消费者
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满足两个模型的加号?我不总是需要检查我的消费者是否有效并附加,但这也允许动态连接?

模型差异的正确用语是什么?我不认为它的延迟加载和动态绑定。请指教。

1 个答案:

答案 0 :(得分:0)

方法1导致内存泄漏,因为必须释放Consumer,A将被删除。引用将是有效的,但它不会在销毁时销毁对象,因此您仍然需要记住"关于释放B,这消除了第一种方法的优势。

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

并且不要忘记添加"明确"到一个参数的构造函数。