1

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

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

namespace AcmesUglyStuff {
    #include <acme_stuff.h>   // declares a struct Thing
}
class Thing {
 public:
    ...
 private:
    AcmesUglyStuff::Thing thing;
}; 

链接将是一个问题。

我能想到的包装库的唯一方法,而不是用 C 库名称污染我的命名空间,是这样的 hack,在类中保留空间:

// 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
}

这是唯一的方法吗?我想避免在我的所有类名上加上前缀,比如XYThing等。

4

3 回答 3

3

似乎你让这变得比它需要的更难。

#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;
};

}

在您的实现文件中#include "acme_stuff.h",在您的构造函数中创建一个new ::Thing对象并将其地址存储在 中acme_thing,在您的析构函数中删除它,并在您的成员函数中强制acme_thing转换为 type ::Thing*

于 2012-09-28T21:13:04.427 回答
0

尝试将某事物命名为与其他事物完全相同的事物并不是一个好主意。(我的意思是相等的完全限定名称,包括所有名称空间。)如果某个库已经在全局名称空间中获取了明显的最佳名称,则您需要选择一个不同的名称。

您可以按照 Pete Becker 的建议将您的Thing放在命名空间中,然后使用它::Thing来访问 Acme 的Thing. 如果您准备始终通过其完全命名空间限定的名称(例如 )来访问您的类,那将会很好My::Thing。尝试using My::Thing;or很诱人using namespace My;,但这不起作用,因为任何包含类定义的翻译单元(例如,通过您创建的头文件)必须首先将 Acme 拉Thing入全局命名空间(否则为“未定义符号”编译解析 ) 的定义时会发生错误My::Thing

于 2012-09-28T21:40:25.710 回答
-1

它真的是一个C API 吗?尝试使用extern "C" {}整个包含的标题来解决链接问题。

namespace AcmesUglyStuff {
  extern "C" {
    #include <acme_stuff.h>
  }
}
于 2012-09-28T21:05:54.767 回答