Created
August 18, 2018 06:33
-
-
Save lixingcong/65a5cfe09340cd49d43ca9f5a7556910 to your computer and use it in GitHub Desktop.
C++的pimpl机制demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* cpp14_pointers.h | |
* | |
* Note: std::make_unique was introduced in C++14. | |
* For C++11, this header will roll the implementation. | |
* | |
* https://stackoverflow.com/questions/17902405/how-to-implement-make-unique-function-in-c11/17902439#17902439 | |
* | |
*/ | |
#ifndef CPP14_POINTERS_H_ | |
#define CPP14_POINTERS_H_ | |
#include <cstddef> | |
#include <memory> | |
#include <type_traits> | |
#include <utility> | |
#if __cplusplus <= 201103L | |
namespace std { | |
template<class T> struct _Unique_if { | |
typedef unique_ptr<T> _Single_object; | |
}; | |
template<class T> struct _Unique_if<T[]> { | |
typedef unique_ptr<T[]> _Unknown_bound; | |
}; | |
template<class T, size_t N> struct _Unique_if<T[N]> { | |
typedef void _Known_bound; | |
}; | |
template<class T, class ... Args> | |
typename _Unique_if<T>::_Single_object make_unique(Args&&... args) | |
{ | |
return unique_ptr<T>(new T(std::forward<Args>(args)...)); | |
} | |
template<class T> | |
typename _Unique_if<T>::_Unknown_bound make_unique(size_t n) | |
{ | |
typedef typename remove_extent<T>::type U; | |
return unique_ptr<T>(new U[n]()); | |
} | |
template<class T, class ... Args> | |
typename _Unique_if<T>::_Known_bound make_unique(Args&&...) = delete; | |
} | |
#endif // __cplusplus | |
#endif /* CPP14_POINTERS_H_ */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
using namespace std; | |
#include "Person.h" | |
int main() | |
{ | |
Person p("Tony"); | |
cout<<"Name="<<p.getName()<<endl; | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Person.h" | |
#include "PersonPrivate.h" | |
#include "cpp14_pointers.h" | |
Person::Person(std::string name): | |
pimpl(std::make_unique<PersonPrivate>(name)) | |
{ | |
} | |
Person::~Person() | |
{ | |
} | |
void Person::setName(std::string name) | |
{ | |
pimpl->name=name; | |
} | |
std::string Person::getName() | |
{ | |
return pimpl->name; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef PERSON_H_ | |
#define PERSON_H_ | |
#include <string> | |
#include <memory> | |
class PersonPrivate; | |
class Person { | |
public: | |
Person(std::string name); | |
~Person(); // Deconstructor need to be declared for unique_ptr | |
void setName(std::string name); | |
std::string getName(); | |
private: | |
// Tips: unique_ptr requires C++11 | |
friend class PersonPrivate; | |
std::unique_ptr<PersonPrivate> pimpl; | |
}; | |
#endif /* PERSON_H_ */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef PERSONPRIVATE_H_ | |
#define PERSONPRIVATE_H_ | |
#include <string> | |
class PersonPrivate { | |
public: | |
PersonPrivate(std::string name):name(name){/* ... */} | |
std::string name; | |
}; | |
#endif /* PERSONPRIVATE_H_ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
PImpl是
Pointer to implementation
的缩写, 是C++ 在构建导出库接口时特有的技术手段。 即是将类Class中所有私有变量以及私有方法,封装在一单独的实现类ClassImpl中。我们在Class中通过一指向ClassImpl的私有指针,访问这些私有数据。而ClassImpl类的具体定义和实现,我们放入cpp中。Qt中的D-Pointer技术,便是PImpl机制的一种实现方式。
优点:
缺点:
摘自《PImpl机制以及Qt的D-Pointer实现》