c ++对象模型的缺点。解决办法是什么?

时间:2013-02-27 12:38:41

标签: c++

我正处于c ++的学习阶段。在阅读c ++对象模型时,我明白了 不同的对象模型。

1)简单对象模型。

2)表驱动对象模型。

3)c ++对象模型。

问题:

它的主要缺点是需要重新编译未修改的代码,该代码使用了一个类的对象,其中添加,删除或修改了非静态类数据成员。

我理解上述陈述。然后,在类定义中发生的任何更改 需要重新编译使用相同类的源代码。

这意味着,有一些原因可以实现相同而无需重新编译。怎么做?如果有人提供了很棒的示例代码。我在Linux / Ubuntu中使用g ++。

3 个答案:

答案 0 :(得分:6)

在修改类时防止重新编译的典型习惯是PImpl。

http://en.wikipedia.org/wiki/Opaque_pointer#C.2B.2B

答案 1 :(得分:1)

可能有其他方法可以在其他语言/对象模型中实现相同的功能,但在C ++中却没有。否则,这不会是C ++对象模型的缺点。

然而,可以减轻后果,例如通过(1)仅从库中导出接口a.k.a.纯抽象类,以及(2)从不改变已发布的接口。如果必须添加新API,请通过新接口导出它(即使它引用了旧的/修改过的实现类)。

我不确定代码示例会对此有多大帮助。这不是编码技术。如果你知道什么是纯粹的抽象类,那么你就已经完成了。

答案 2 :(得分:0)

请注意,在标头中公开实现细节可能会有优势,并且在细节发生变化时强制重新编译的缺点也是如此;函数可以更容易内联,这可以提高运行时性能。您需要决定在何处以及何时权衡这笔费用。

通过引入额外级别的间接,可以隐藏源文件中的所有私有实现细节。一种常见的方法是指向私有实现(或“pimpl”)习语,例如:

// Header file
class Thing {
public:
    Thing(...);
    ~Thing();

    // Public interface

private:
    struct Impl;
    std::unique_ptr<Impl> impl;
};

// Source file
struct Thing::Impl {
    // private details
};

Thing(...) : impl(new Impl(...)) {}
~Thing() {}

// Implementation of public interface

另一种可能性是定义一个抽象接口,使用一个或多个工厂来创建包含实现的具体实例,例如:

// Header file
class Thing {
public:
    virtual ~Thing() {}

    static std::unique_ptr<Thing> make(...);

    // Pure virtual public interface
};

// Source file
class ThingImpl : public Thing {
    // Implementation of public interface

    // Private implementation details
};

std::unique_ptr<Thing> Thing::make(...) {
    return std::unique_ptr<Thing>(new ThingImpl(...));
}

这两种方法都将所有实现细节都放在源文件中,因此在细节发生变化时,这是唯一需要重新编译的东西。但两者都引入了额外的指针间接和/或间接函数调用,这可能会影响运行时性能。