定义
一种C++的编程手法,一方面可以减少编译依赖,对于大工程来说可以减少编译时间,一方面对于库来说可以减少私有成员的暴露,减少风险。
demo
class Student
{
Student(int age, string name, int sex);
~Student();
string show();
private:
int m_age;
string m_name;
int m_sex;
}
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三个头文件使用,我们可以看到,一旦动了学生类,那么依赖的这三个类都要重新编译。
优化
class StudentImpl;
class Student
{
Student(int age, string name, int sex);
~Student();
string show();
private:
shared_ptr<StudentImpl> m_student;
}
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;
}
StudentImpl::StudentImpl(int age, string name, int sex):m_age(age),m_name(name), m_sex(sex){};
Student::Student(int age, string name, int sex)
{
m_student = make_shared<StudentImpl>(age,name,sex);
};
string Student::show(){return student->name();};
这样的话,你就是student.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;
}
std::shared_ptr<ThreadLocalAllocatorImpl> GetAllocator() {
return allocator_;
}
private:
std::shared_ptr<ThreadLocalAllocatorImpl> allocator_;
};
class ThreadLocalAllocatorImpl
: public std::enable_shared_from_this<ThreadLocalAllocatorImpl> {
public:
ThreadLocalAllocatorImpl(Place& p);
ThreadLocalAllocation* AllocateImpl(size_t size);
void FreeImpl(ThreadLocalAllocation* allocation);
uint64_t ReleaseImpl();
private:
unique_ptr<BuddyAllocator> buddy_allocator_;
Place place_;
};
上面这段代码是抽取一个allocator相关代码,整个库中有非常非常多的这种,但是有个问题是ThreadLocalAllocatorImpl和ThreadLocalAllocator在一个文件中,正确的写法是ThreadLocalAllocatorImpl应该在thread_local_alloctor.cpp,如果按当下的写法一旦改变private成员,依赖这个thread_local_alloctor.h的文件都会重新编译,所以这个IMPL的意义是什么?是有什么高深的用法吗?不知道是大佬写错了还是我会错意了,希望懂得大神能留言解释一下。
|