tjw*_*992 1 c++ oop optimization pimpl-idiom dependency-management
我已经看到PIMPL习语以两种不同的方式实现.一种方法是始终使实现成为类的私有成员.这确保了无论如何都无法从类外部访问实现.
例如:
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 */
Run Code Online (Sandbox Code Playgroud)
Example.cpp
#include "Example.h"
#include <iostream>
struct Example::Impl {
void doSomething() {
std::cout << "Hello World!" << std::endl;
}
};
void Example::doSomething() {
pimpl_->doSomething();
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "Example.h"
int main() {
Example ex;
ex.doSomething();
system("pause");
}
Run Code Online (Sandbox Code Playgroud)
我看到的另一种方法是使用它自己的.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 */
Run Code Online (Sandbox Code Playgroud)
ExampleImpl.h
#ifndef EXAMPLE_IMPL_H
#define EXAMPLE_IMPL_H
struct ExampleImpl {
public:
void doSomething();
};
#endif /* EXAMPLE_IMPL_H */
Run Code Online (Sandbox Code Playgroud)
Example.cpp
#include "Example.h"
#include "ExampleImpl.h"
#include <iostream>
void Example::doSomething() {
pimpl_->doSomething();
}
Run Code Online (Sandbox Code Playgroud)
ExampleImpl.cpp
#include "ExampleImpl.h"
#include <iostream>
void ExampleImpl::doSomething() {
std::cout << "Hello World!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "Example.h"
int main() {
Example ex;
ex.doSomething();
system("pause");
}
Run Code Online (Sandbox Code Playgroud)
我能看到的唯一值得注意的差异是使用第二种方法,您可以访问实现而无需通过Example该类.我个人没有看到任何人为什么需要这样做的原因.
这两种方法似乎都能起作用并满足最终目标,但选择一种方法比另一种方法有什么真正的优势吗?
显然,这是一个意见问题.
我认为使用第二种方法违背了Pimpl习语的精神.
Example,则很可能会影响四个文件而不是两个文件.ExampleImpl,则很可能会影响三个文件而不是一个文件.鉴于以上几点,我建议使用嵌套类方法.