对于许多C ++开发人员来说,API设计可能会在其优先级列表中排名第3或第4。大多数开发人员都倾向于使用C ++来获得原始功能和控制权。因此,性能和优化的想法占据这些开发者的时间的百分之八十。
当然,每个C ++开发人员都会考虑头文件设计的各个方面,但是API设计不仅仅是头文件设计那样。事实上,我强烈建议每一个开发人员在其API的设计上,无论是面向公共还是面向内部,都给予一些帮助,因为这样可以节省你大量的维护成本,提供平滑的升级路径,并为你的客户节省麻烦。
下面列出的许多错误都是我自己的经验和我从Martin Reddy的精彩书籍《C ++ API Design》(我强烈推荐的书)中学到的东西的结合。如果你真的想要深入了解C ++ API设计,那么你应该阅读Martin Reddy的书,然后使用下面的列表作为更多的清单来强制执行代码审查。
为什么这是一个错误?
因为你不知道将使用哪个代码库,特别是对于外部API。如果不将API功能限制在命名空间中,则可能导致与该系统中使用的其他API发生名称冲突。
例如:让我们考虑一个非常简单的API和使用它的客户端类:
//API - In Location.h
class vector
{
public:
vector(double x, double y, double z);
private:
double xCoordinate;
double yCoordinate;
double zCoordinate;
};
//Client Program
#include "stdafx.h"
#include "Location.h"
#include <vector>
using namespace std;
int main()
{
vector<int> myVector;
myVector.push_back(99);
return 0;
}
如果有人试图在同时使用std::vector的项目中使用这个类,他们会得到一个错误:
“error C2872: ‘vector’: ambiguous symbol”
这是因为编译器无法决定客户端代码引用的向量是std::vector还是location.h中定义的vector对象。
如何解决这个问题?
始终将API放在自定义命名空间中,例如:
//API
namespace LocationAPI
{
class vector
{
public:
vector(double x, double y, double z);
private:
double xCoordinate;
double yCoordinate;
double zCoordinate;
};
}
另一种方法是为所有公共API符号添加一个唯一的前缀。如果遵循此约定,我们将调用我们的类“lvector”而不是“vector”。此方法用于OpenGL和QT。
在我看来,如果你正在开发纯C的API,这是有道理的。确保所有公共符号符合此唯一命名约定是另一个令人头痛的问题。如果你正在使用C ++,那么你应该只在命名空间中对API功能进行分组,让编译器为你完成繁重的任务。
我还强烈建议你使用嵌套命名空间来进行功能分组或将公共API与内部API分开。一个很好的例子是Boost库,它们可以自由地使用嵌套的命名空间。例如,在根“boost”命名空间内,boost :: variant包含Boost Variant API的公共符号,boost :: detail :: variant包含该API的内部详细信息。
为什么这是一个错误?
这将导致被引用命名空间中的所有符号在全局命名空间中变得可见,并首先抵消掉使用命名空间的好处。
另外:
如何解决这个问题?
//File:MyHeader.h:
class MyClass
{
private:
Microsoft::WRL::ComPtr _parent;
Microsoft::WRL::ComPtr _child;
}
//File:MyHeader.h:
class MyClass
{
namespace wrl = Microsoft::WRL; // note the aliasing here !
private:
wrl::ComPtr _parent;
wrl::ComPtr _child;
}
有关与C ++头文件相关的其他问题,请参阅帖子“十大C ++头文件错误以及如何修复它们”(https://www.acodersjourney.com/top-10-c-header-file-mistakes-and-how-to-fix-them/)。
more to read at https://mp.weixin.qq.com/s/Yyno5VNHr88BaQvMoZafVA
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。