【发布时间】:2018-09-18 13:37:33
【问题描述】:
我有 1 个 .h 文件 test.h 包含一个类。在这个类中,有一个私有方法返回一个我不想“公开”的类型的指针,但我希望能够将这个 test.h 文件包含在其他源文件中。
一般来说,在 .h 文件中使用前向声明很容易:
class Foo;
但问题是这种类型来自一个 C 文件我无法更改(因为它是我没有维护的其他代码)并且它是一个 typedef。
所以基本上我的test.cpp 是:
// this type comes from a C file, cannot be changed to struct or class
typedef struct
{
int x;
} Foo;
#include "test.h"
static Foo foo;
Foo *Test::private_function()
{
foo.x = 12;
return &foo;
}
int Test::compute()
{
auto *local_foo = private_function();
return local_foo->x;
}
而我的test.h 文件是:
#pragma once
struct Foo;
class Test
{
public:
Test() {}
int compute();
private:
Foo *private_function();
};
尝试编译失败:
>g++ -std=c++11 -c test.cpp
In file included from test.cpp:10:0:
test.h:3:8: error: using typedef-name 'Foo' after 'struct'
test.cpp:7:3: note: 'Foo' has a previous declaration here
目前我的解决方法是返回void * 并来回执行static_cast,但我认为这不是最佳的。有更好的解决方案吗?
(我已经检查了Forward declaration of a typedef in C++,但我测试了解决方案,但它们似乎不适用于我的情况,也许我想做的更简单/不同 - 我只有一个 .h 和 .cpp - 或者只是不可能)
【问题讨论】:
-
很遗憾,
typedefs 无法前向声明。一种常见的解决方法是拥有一个从 C 结构继承的 C++ 类,由其 typedef 引用,您可以前向声明它。这将需要一些代码更改,但它们应该是最小的。 -
@SamVarshavchik 看起来像是一个有效的答案。我刚刚在我的示例 (
class FooC : public Foo {};) 上尝试过,它成功了。 Tme 在我的真实案例中进行测试。非常感谢您:) 发布您的答案并收集 25+ -
这并没有解决问题,但请注意
extern "C"周围的stuct定义没有做任何事情。那里没有任何外部联系。extern "C"并不意味着“将其编译为 C 代码”;它的意思是“生成可以与我的本地 C 编译器生成的代码链接的目标代码”。