C++中的pimpl用法(Pointer to Implementation)

定义

一种C++的编程手法,一方面可以减少编译依赖,对于大工程来说可以减少编译时间,一方面对于库来说可以减少私有成员的暴露,减少风险。

demo

// student.h
class Student
{
	Student(int age, string name, int sex);
	~Student();
	string show();
private:
	int m_age;
	string m_name;
	int m_sex;
}
// student.cpp
string Student::show(){return m_name;};
Student::Student(int age, string name, int sex):m_age(age),\
m_name(name), m_sex(sex){};

上面是一个学生类的定义和实现,现在如果想用这个学生类的有school.h , teacher.h, parent.h三个头文件使用,我们可以看到,一旦动了学生类,那么依赖的这三个类都要重新编译。

优化

// student.h
class StudentImpl;
class Student
{
	Student(int age, string name, int sex);
	~Student();
	string show();
private:
	shared_ptr<StudentImpl> m_student;
 }
//student_impl.h
class StudentImpl
{
StudentImpl(int age, string name, int sex);
~StudentImpl();
string name(){return m_name;};

private:
	int m_age;
	string m_name;
	int m_sex;
}
//student_impl.cpp
StudentImpl::StudentImpl(int age, string name, int sex):m_age(age),m_name(name), m_sex(sex){};

// student.cpp
#include "student_impl.h"
#include "student.h"
Student::Student(int age, string name, int sex)
{
   m_student = make_shared<StudentImpl>(age,name,sex);
};
string Student::show(){return student->name();};

这样的话,你就是student.cpp接口改翻天,此外你的实现也就是成员变量student_impl.h/cpp改翻天也不影响school.h , teacher.h, parent.h,因为他们理论来说编译的时候不依赖StudentImpl,这样在大型项目中,就可以加快编译速度,此外如果代码是提供对外的库比如opencv,一般会给一个头文件和so, 这里会有一个student.h,可是student.so外人压根不知道这个类的私有成员是啥,你也很难推出库函数的逻辑,保护了算法和知识产权。

paddle案例

位置:paddle/fluid/memory/allocation/thread_local_alloctor.h

class ThreadLocalAllocatorImpl;

class ThreadLocalAllocation : public Allocation {
 public:
  ThreadLocalAllocation(void* ptr, size_t size, platform::Place place)
      : Allocation(ptr, size, place) {}

  void SetThreadLocalAllocatorImpl(
      std::shared_ptr<ThreadLocalAllocatorImpl> allocator) {
    allocator_ = allocator;
  }  //给impl指针赋值

  std::shared_ptr<ThreadLocalAllocatorImpl> GetAllocator() {
    return allocator_;
  } //获取impl指针

 private:
  std::shared_ptr<ThreadLocalAllocatorImpl> allocator_;
};

class ThreadLocalAllocatorImpl
    : public std::enable_shared_from_this<ThreadLocalAllocatorImpl> {
 public:
  ThreadLocalAllocatorImpl(Place& p);
  ThreadLocalAllocation* AllocateImpl(size_t size);//不要觉得奇怪,一个类可以在自己内部声明一个指针的,这里可以理解为AllocateImpl是在ThreadLocalAllocation类中。
  void FreeImpl(ThreadLocalAllocation* allocation);//理解同上
  uint64_t ReleaseImpl();

 private:
  unique_ptr<BuddyAllocator> buddy_allocator_;//理解在ThreadLocalAllocation类中。
  Place place_;//同上
};

上面这段代码是抽取一个allocator相关代码,整个库中有非常非常多的这种,但是有个问题是ThreadLocalAllocatorImpl和ThreadLocalAllocator在一个文件中,正确的写法是ThreadLocalAllocatorImpl应该在thread_local_alloctor.cpp,如果按当下的写法一旦改变private成员,依赖这个thread_local_alloctor.h的文件都会重新编译,所以这个IMPL的意义是什么?是有什么高深的用法吗?不知道是大佬写错了还是我会错意了,希望懂得大神能留言解释一下。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值