废话不多说,先来一段代码:
class Urg_driver : public Lidar
{
public:
enum {
Default_baudrate = 115200,
Default_port = 10940,
Infinity_times = -1,
};
Urg_driver(void);
virtual ~Urg_driver(void);
static std::vector<std::string> find_ports(void);
static std::vector<std::string> find_ports(std::vector<int>&
is_urg_ports);
const char* what(void) const;
bool open(const char* device_name, long baudrate = Default_baudrate,
connection_type_t type = Serial);
void close(void);
bool is_open(void) const;
void set_timeout_msec(int msec);
bool laser_on(void);
bool laser_off(void);
void reboot(void);
void sleep(void);
void wakeup(void);
bool is_stable(void);
//! Starts data measurement process
bool start_measurement(measurement_type_t type = Distance,
int scan_times = Infinity_times,
int skip_scan = 0);
//! Receives measurement data
bool get_distance(std::vector<long>& data, long *time_stamp = NULL);
bool get_distance_intensity(std::vector<long>& data,
std::vector<unsigned short>& intensity,
long *time_stamp = NULL);
bool get_multiecho(std::vector<long>& data_multi,
long* time_stamp = NULL);
bool get_multiecho_intensity(std::vector<long>& data_multiecho,
std::vector<unsigned short>&
intensity_multiecho,
long* time_stamp = NULL);
bool set_scanning_parameter(int first_step, int last_step,
int skip_step = 1);
//! Stops data measurement process
void stop_measurement(void);
//! Synchronization of timestamps
bool set_sensor_time_stamp(long time_stamp);
long get_sensor_time_stamp(void);
//! Angle conversion functions
double index2rad(int index) const;
double index2deg(int index) const;
int rad2index(double radian) const;
int deg2index(double degree) const;
int rad2step(double radian) const;
int deg2step(double degree) const;
double step2rad(int step) const;
double step2deg(int step) const;
int step2index(int step) const;
int min_step(void) const;
int max_step(void) const;
long min_distance(void) const;
long max_distance(void) const;
long scan_usec(void) const;
int max_data_size(void) const;
int max_echo_size(void) const;
const char* product_type(void) const;
const char* firmware_version(void) const;
const char* serial_id(void) const;
const char* status(void) const;
const char* state(void) const;
int raw_write(const char* data, size_t data_size);
int raw_read(char* data, size_t max_data_size, int timeout);
int raw_readline(char* data, size_t max_data_size, int timeout);
void* raw_urg(void);
void set_measurement_type(measurement_type_t type);
private:
Urg_driver(const Urg_driver& rhs);
Urg_driver& operator = (const Urg_driver& rhs);
struct pImpl;/////!!!!!!就是它,技巧就这里
std::auto_ptr<pImpl> pimpl;
};
}
然后接着看:
void Urg_driver::stop_measurement(void)
{
urg_stop_measurement(&pimpl->urg_);
}
long Urg_driver::get_sensor_time_stamp(void)
{
return urg_time_stamp(&pimpl->urg_);
}
double Urg_driver::index2rad(int index) const
{
return urg_index2rad(&pimpl->urg_, index);
}
double Urg_driver::index2deg(int index) const
{
return urg_index2deg(&pimpl->urg_, index);
}
int Urg_driver::rad2index(double radian) const
{
return urg_rad2index(&pimpl->urg_, radian);
}
int Urg_driver::deg2index(double degree) const
{
return urg_deg2index(&pimpl->urg_, degree);
}
int Urg_driver::rad2step(double radian) const
{
return urg_rad2step(&pimpl->urg_, radian);
}
int Urg_driver::deg2step(double degree) const
{
return urg_deg2step(&pimpl->urg_, degree);
}
double Urg_driver::step2rad(int step) const
{
return urg_step2rad(&pimpl->urg_, step);
}
double Urg_driver::step2deg(int step) const
{
return urg_step2deg(&pimpl->urg_, step);
}
int Urg_driver::step2index(int step) const
{
return urg_step2index(&pimpl->urg_, step);
}
int Urg_driver::min_step(void) const
{
int min_step;
int max_step;
urg_step_min_max(&pimpl->urg_, &min_step, &max_step);
return min_step;
}
大家注意到函数的实现没有?每个参数都有一个神奇的:
&pimpl->urg_
这个东西是什么呢?为什么会出现?然后我们仔细看代码实现,找到了它:
struct Urg_driver::pImpl
{
urg_t urg_;
bool is_opened_;
measurement_type_t last_measure_type_;
long time_stamp_offset_;
string product_type_;
string firmware_version_;
string serial_id_;
string status_;
string state_;
pImpl(void)
: is_opened_(false), last_measure_type_(Distance), time_stamp_offset_(0)
{
}
void adjust_time_stamp(long *time_stamp)
{
if (time_stamp) {
*time_stamp += time_stamp_offset_;
}
}
};
这是一个结构体,本文章的意义就在于说明作者为什么要这么用:
分析这个结构体的特点:
1.它包含了所有的基础的操作变量。
2.里面包含了基础的私有变量操作。
3.减少了头文件的代码行数!!!。
4.当进行逐层封装的时候,让封装的可读性变好。一层覆盖一层