c++ - 使用 PIMPL 习惯用法,实现是否应该始终是类的私有(private)成员?

标签 c++ oop optimization dependency-management pimpl-idiom

我看过 PIMPL idiom以两种不同的方式实现。一种方法是始终使实现成为类的私有(private)成员。这确保无论如何都无法从类外部访问实现。

例如:

Example.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

#include <memory>

class Example {
public:
    void doSomething();
private:
    struct Impl;
    std::shared_ptr<Impl> pimpl_;
};

#endif /* EXAMPLE_H */

示例.cpp

#include "Example.h"
#include <iostream>

struct Example::Impl {
    void doSomething() {
        std::cout << "Hello World!" << std::endl;
    }
};

void Example::doSomething() {
    pimpl_->doSomething();
}

main.cpp

#include "Example.h"

int main() {
    Example ex;
    ex.doSomething();
    system("pause");
}

我见过的另一种方法是使实现成为一个完全独立的类,它有自己的 .h 文件和自己的 .cpp 文件。

例如:

Example.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

#include <memory>

struct ExampleImpl;

class Example {
public:
    void doSomething();
private:
    std::shared_ptr<ExampleImpl> pimpl_;
};

#endif /* EXAMPLE_H */

ExampleImpl.h

#ifndef EXAMPLE_IMPL_H
#define EXAMPLE_IMPL_H

struct ExampleImpl {
public:
    void doSomething();
};

#endif /* EXAMPLE_IMPL_H */

示例.cpp

#include "Example.h"
#include "ExampleImpl.h"
#include <iostream>

void Example::doSomething() {
    pimpl_->doSomething();
}

ExampleImpl.cpp

#include "ExampleImpl.h"
#include <iostream>

void ExampleImpl::doSomething() {
    std::cout << "Hello World!" << std::endl;
}

main.cpp

#include "Example.h"

int main() {
    Example ex;
    ex.doSomething();
    system("pause");
}

我能看到的唯一显着区别是使用第二种方法,您无需通过 Example 类即可访问实现。不过,我个人认为没有任何理由需要这样做。

这两种方法似乎都有效并满足最终目标,但是选择一种方法比另一种方法有什么真正的优势吗?

最佳答案

这显然是一个见仁见智的问题。

我认为使用第二种方法违背了 Pimpl 习语的精神。

  1. 现在外部可以看到实现细节。
  2. 如果对 Example 的界面进行任何更改,它很可能会影响四个文件而不是两个。
  3. 如果对 ExampleImpl 的实现方式进行任何更改,很可能会影响三个文件,而不是一个。

鉴于以上几点,我建议使用嵌套类方法。

关于c++ - 使用 PIMPL 习惯用法,实现是否应该始终是类的私有(private)成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45421287/

相关文章:

c++ - 如何在不属于家庭的类(class)之间共享枚举?

PHP 面向对象 - 真实案例

java - 如何在另一个类中使用方法(在 Try-Catch 内)中的变量?

Android M startActivity 电池优化

android - QT+Android+Lib = VFP错误

c++ - OpenCL 重用具有不同 DEFINE (-D) 的 cl_kernel

每个循环的 C++ vector 不会遍历引用?

c++ - Mingw-w64 + 代码块 : No such file or directory

wpf - 过多的数据绑定(bind)是否会使 WPF 应用程序变慢?有哪些可用的优化技术?

python - 查找给定范围内其除数之和具有完美平方的数字,并将它们与相关平方一起返回