C++ 如何在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:

假设Acme公司发布了一个有用的库,其中包含一个极其丑陋的C API。我想在C++类中包装结构和相关函数。似乎我不能对包装类使用相同的名称,因为原始库不在名称空间中

像这样的事情是不可能的,对吧

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东西
拉入全局命名空间(否则在解析
My::Thing
的定义时会发生“未定义符号”编译错误)。

警告:前方有个坏主意,小心行事。。。如果你的代码< >定义了< /Cord>其他的结构名,导入头,然后<代码> >“unDEF< <代码> >结构类,写出你的类,这是完美C++接口(与丑陋的C接口相反)的好习惯,将它保存在某个命名空间中。把它看作是好东西——<代码>名称空间PrimeCppPoalSo界面{class对象{};} /Coo>希望有一天模块将成为C++标准的一部分。但是每个人都会这样做,并且干净地解决了这个问题。
extern“C”
如何帮助
C
struct Thing
vs
C++
class Thing
问题?@PiotrNycz:就像OP在第一个代码块中所做的那样?您使用
AcmesUglyStuff::Thing
来引用C结构。在我的小测试程序中,这似乎是可行的,但我不知道为什么。我希望它不会链接,但我猜如果符号是extern C,那么它们就不会在名称空间中被损坏或包装。经过更多的实验后,我可能会将此标记为一个答案。-1这是一个维护噩梦。要了解原因,请使用