C++ 使用称为“pimpl”(私有实现/指向实现的指针)的习语来隐藏实现细节。有关详细信息,请查看此 MSDN 文章。
简而言之,您像往常一样在头文件中公开您的接口。让我们以您的代码为例:
tTemp.h
class tTemp {
private:
class ttemp_impl; // forward declare the implementation class
std::unique_ptr<ttemp_impl> pimpl;
public:
tTemp ();
~tTemp ();
setTemp (double);
double getTemp (void);
double getTempF (void);
};
公共接口仍然存在,但私有内部已被替换为指向私有实现类的智能指针。该实现类仅位于头文件对应的.cpp 文件中,不公开。
tTemp.cpp
class tTemp::ttemp_impl
{
// put your implementation details here
}
// use the pimpl as necessary from the public interface
// be sure to initialize the pimpl!
tTtemp::tTemp() : pimpl(new ttemp_impl) {}
这还有一个额外的优势,即允许您在不更改标题的情况下更改类的内部结构,这意味着您的类用户需要更少的重新编译。
对于 paxdiablo 的 pre-C++11 答案中所示的完整解决方案,但使用unique_ptr
而不是void *
,您可以使用以下内容。首先ttemp.h
:
#include <memory>
class tTemp {
public:
tTemp();
~tTemp();
void setTemp(double);
double getTemp (void);
double getTempF (void);
private:
class impl;
std::unique_ptr<impl> pimpl;
};
接下来,“隐藏”实现ttemp.cpp
:
#include "ttemp.h"
struct tTemp::impl {
double temp;
impl() { temp = 0; };
double tempF (void) { return temp * 9 / 5 + 32; };
};
tTemp::tTemp() : pimpl (new tTemp::impl()) {};
tTemp::~tTemp() {}
void tTemp::setTemp (double t) { pimpl->temp = t; }
double tTemp::getTemp (void) { return pimpl->temp; }
double tTemp::getTempF (void) { return pimpl->tempF(); }
最后,ttemp_test.cpp
:
#include <iostream>
#include <cstdlib>
#include "ttemp.h"
int main (void) {
tTemp t;
std::cout << t.getTemp() << "C is " << t.getTempF() << "F\n";
return 0;
}
而且,就像 paxdiablo 的解决方案一样,输出是:
0C is 32F
具有更多类型安全性的附加优势。这个答案是 C++11 的理想解决方案,如果您的编译器是 C++11 之前的版本,请参阅 paxdiablo 的答案。