all*_*llo 2 c++ api-design include
我想将一个类实现分为三个部分,以避免用户需要处理实现细节,例如,我用来实现功能的库:
impl.cpp
#include <api.h>
#include <impl.h>
Class::Class() {
init();
}
Class::init() {
myData = SomeLibrary::Type(42);
}
Class::doSomething() {
myData.doSomething();
}
Run Code Online (Sandbox Code Playgroud)
展示次数
#include <somelibrary.h>
class Class {
public:
Class();
init();
doSomething();
private:
SomeLibary::Type myData;
}
Run Code Online (Sandbox Code Playgroud)
api.h
class Class {
Class();
doSomething();
}
Run Code Online (Sandbox Code Playgroud)
问题是,不允许我为类定义重新定义标题。当我定义这不起作用Class(),并doSomething()只在api.h,无论是。
一个可能的选择是定义api.h它,并且根本不在项目中使用它,而是安装它(而不安装impl.h)。
最明显的缺点是,我需要确保,在常见的方法api.h,并impl.h始终具有相同的签名,否则使用库会得到链接错误,在编译库时,我无法预测程序。
但是,这种方法是否会奏效,还是会由于obj文件与标头不匹配而引起其他问题(例如,指向类成员的指针错误或类似问题)?
最简洁的答案是不!”
原因是:需要使用您的Class类的任何/所有“客户端”项目都必须具有该类的完整声明,以便编译器可以正确地确定诸如成员变量的偏移量之类的内容。
private成员的使用很好-客户端程序将无法更改它们-就像您当前的实现一样,标头中仅提供成员函数的最简单的概述,而(私有)源文件中包含所有实际的定义。
解决此问题的一种可能方法是在中声明一个指向嵌套类的指针Class,该嵌套类仅在共享标头中声明:class NestedClass然后,您可以在实现中使用该嵌套类指针执行所需的操作。通常,您可以使嵌套的类指针成为private成员。同样,由于在共享头文件中未给出其定义,因此“客户端”项目尝试访问该类的任何尝试(而不是作为指针)都将是编译器错误。
这是一个可能的代码故障(也许不是无错误的,因为它是一种快速的输入):
// impl.h
struct MyInternal; // An 'opaque' structure - the definition is For Your Eyes Only
class Class {
public:
Class();
init();
doSomething();
private:
MyInternal* hidden; // CLient never needs to access this! Compiler error if attempted.
}
// impl.cpp
#include <api.h>
#include <impl.h>
struct MyInternal {
SomeLibrary::Type myData;
};
Class::Class() {
init();
}
Class::init() {
hidden = new MyInternal; // MUCH BETTER TO USE unique_ptr, or some other STL.
hidden->myData = SomeLibrary::Type(42);
}
Class::doSomething() {
hidden->myData.doSomething();
}
Run Code Online (Sandbox Code Playgroud)
注意:正如我在代码注释中所暗示的那样,最好使用代码std::unique_ptr<MyInternal> hidden。但是,这将要求您在自己的析构函数,赋值运算符和其他变量(移动运算符?复制构造函数?)中给出明确的定义Class,因为它们将需要访问该MyInternal结构的完整定义。
| 归档时间: |
|
| 查看次数: |
104 次 |
| 最近记录: |