我有一个头文件(例如 the_foo.h),它定义/声明了以下类:
// \file the_foo.h
class FooBase
{
virtual size_t bar_size() = 0;
};
template<class Bar>
class Foo : public FooBase
{
size_t bar_size() { return sizeof(Bar); }
};
class TheBar; // TheBar forward declaration
class TheFoo : public Foo<TheBar>
{
};
使用 MS vc14 (Visual Studio 2015) 编译时,我注意到以下行为:
任何包含 the_foo.h 并定义
TheBar
的 cpp 文件,例如:#include "the_foo.h" 类 TheBar {};//TheBar 定义
会编译得很好。然而,
任何包含 the_foo.h 和 DOES NOT DEFINE
TheBar
的 cpp 文件,例如:#include "the_foo.h"
编译失败,出现错误:
the_foo.h(11): error C2027: use of undefined type 'TheBar'
上面编译的cpp文件只有一行:包含header,没有更多的代码。
删除虚拟成员函数声明virtual size_t bar_size() = 0;
确实修复了错误。
感谢 Sam Varshavchik 的回答,这段代码使用 gcc 5.3.1 编译得很好,所以这个问题显然是特定于编译器的。
我的问题是:
- 当
TheBar
仅向前声明时,为什么在情况 (2) 中编译失败? - 有什么方法可以使案例 (2) 在 vc14 下成功编译,即没有明确定义
TheBar
,我需要在某些 cpp 文件中保持不透明的类?
PS:我编辑了这个问题的代码示例,以便弄清楚到底是什么导致了问题中描述的问题。原始代码示例(在 Sam Varshavchik 的回答中引用)可能确实误导了问题的实际原因,因此导致答案和评论超出问题范围。
最佳答案
您的测试用例在 gcc 5.3.1 中编译没有问题:
$ cat t.C
class FooBase
{
public:
FooBase() {}
virtual ~FooBase() {}
};
template<class Bar>
class Foo : public FooBase
{
public:
Foo() { sizeof(Bar); bar = new Bar; }
~Foo() { sizeof(Bar); delete bar; }
Bar* bar;
};
class TheBar;
class TheFoo : public Foo<TheBar>
{
public:
TheFoo();
~TheFoo();
};
[mrsam@octopus tmp]$ g++ -c -o t.o t.C
[mrsam@octopus tmp]$
这里的答案似乎是“您使用的旧 C++ 编译器无法正确编译它”。
关于c++ - 在继承自抽象类的模板类中正确使用未定义类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36571453/