C++ 如何在C++;类并保持相同的名称?
假设Acme公司发布了一个有用的库,其中包含一个极其丑陋的C API。我想在C++类中包装结构和相关函数。似乎我不能对包装类使用相同的名称,因为原始库不在名称空间中 像这样的事情是不可能的,对吧C++ 如何在C++;类并保持相同的名称?,c++,namespaces,wrapper,C++,Namespaces,Wrapper,假设Acme公司发布了一个有用的库,其中包含一个极其丑陋的C API。我想在C++类中包装结构和相关函数。似乎我不能对包装类使用相同的名称,因为原始库不在名称空间中 像这样的事情是不可能的,对吧 namespace AcmesUglyStuff { #include <acme_stuff.h> // declares a struct Thing } class Thing { public: ... private: AcmesUglyStuff:
namespace AcmesUglyStuff {
#include <acme_stuff.h> // declares a struct Thing
}
class Thing {
public:
...
private:
AcmesUglyStuff::Thing thing;
};
名称空间AcmesUglyStuff{
#include//声明一个结构对象
}
阶级事务{
公众:
...
私人:
AcmesUglyStuff::东西;
};
链接将是一个问题
我能想到的唯一方法是包装库,而不是用C库名称污染我的名称空间,是这样一种黑客,在类中保留空间:
// In mything.h
namespace wrapper {
class Thing {
public:
...
private:
char impl[SIZE_OF_THING_IN_C_LIB];
};
}
// In thing.cc
#include <acme_stuff.h>
wrapper::Thing::Thing() {
c_lib_function((::Thing*)impl); // Thing here referring to the one in the C lib
}
//在mything.h中
名称空间包装器{
阶级事务{
公众:
...
私人:
char impl[在库中的东西的大小];
};
}
//In thing.cc
#包括
包装器::东西::东西(){
c_lib_函数((::Thing*)impl);//这里的Thing指的是c库中的Thing
}
这是唯一的办法吗?我想避免在我所有的类名上加前缀,比如
XYThing
,等等。它真的是CAPI吗?尝试extern“C”{}
到整个包含的头以解决链接问题
namespace AcmesUglyStuff {
extern "C" {
#include <acme_stuff.h>
}
}
名称空间AcmesUglyStuff{
外部“C”{
#包括
}
}
看来你让这件事变得更难了
#include "acme_stuff.h" // puts all of its names in global namespace
namespace acme {
class Thing {
public:
// whatever
private:
::Thing thing;
};
}
现在只需使用acme::Thing
而不是Thing
如果在全局命名空间中不使用C名称对您来说非常重要,那么您需要一个间接级别:
namespace acme {
class Thing {
public:
Thing();
~Thing();
// whatever
private:
void *acme_thing;
};
}
在您的实现文件中,
#包括“acme_stuff.h”
,在构造函数中创建一个new::Thing
对象,并将其地址存储在acme_Thing
中,在析构函数中删除它,在您的成员函数中,将acme\u thing
转换为键入::thing*
尝试将某个对象与其他对象命名为完全相同的对象不是一个好主意。(我指的是相等的完全限定名称,包括所有名称空间。)如果某个库已经获取了全局名称空间中明显最好的名称,则需要选择其他名称
您可以按照Pete Becker的建议将类
Thing
放在名称空间中,然后使用::Thing
访问Acme的Thing
。如果您准备始终通过类的完全命名空间限定名(例如,My::Thing
)访问该类,那么这将很好。尝试使用My::Thing很有诱惑力
或使用名称空间My但是,因为包含类定义的任何翻译单元(例如,通过您创建的头文件)必须首先将Acme的东西
拉入全局命名空间(否则在解析My::Thing
的定义时会发生“未定义符号”编译错误)。警告:前方有个坏主意,小心行事。。。如果你的代码< >定义了< /Cord>其他的结构名,导入头,然后<代码> >“unDEF< <代码> >结构类,写出你的类,这是完美C++接口(与丑陋的C接口相反)的好习惯,将它保存在某个命名空间中。把它看作是好东西——<代码>名称空间PrimeCppPoalSo界面{class对象{};} /Coo>希望有一天模块将成为C++标准的一部分。但是每个人都会这样做,并且干净地解决了这个问题。extern“C”
如何帮助C
struct Thing
vsC++
class Thing
问题?@PiotrNycz:就像OP在第一个代码块中所做的那样?您使用AcmesUglyStuff::Thing
来引用C结构。在我的小测试程序中,这似乎是可行的,但我不知道为什么。我希望它不会链接,但我猜如果符号是extern C,那么它们就不会在名称空间中被损坏或包装。经过更多的实验后,我可能会将此标记为一个答案。-1这是一个维护噩梦。要了解原因,请使用