-1

我在 C++ 的学习阶段。在阅读 c++ 对象模型时,我了解了不同的对象模型。

1) 简单对象模型。

2) 表驱动对象模型。

3) c++ 对象模型。

问题:

"它的主要缺点是需要重新编译未修改的代码,这些代码利用已添加、删除或修改非静态类数据成员的类的对象。 "

我理解了上面的说法。类定义中发生的任何更改,都需要重新编译使用相同类的源代码。

这意味着,有一些为什么在不重新编译的情况下也能达到同样的效果。怎么做?如果有人提供示例代码,那就太好了。我在 Linux/Ubuntu 中使用 g++。

4

3 回答 3

6

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

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

于 2013-02-27T12:42:02.170 回答
1

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

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

我不确定代码示例会有多大帮助。这不是一种编码技术。如果您知道什么是纯抽象类,那么您就大功告成了。

于 2013-02-27T12:54:48.833 回答
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(...));
}

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

于 2013-02-27T14:17:12.577 回答