c++ - 在继承自抽象类的模板类中正确使用未定义类型

标签 c++ templates visual-c++ abstract-class forward-declaration

我有一个头文件(例如 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) 编译时,我注意到以下行为:

  1. 任何包含 the_foo.h 并定义 TheBar 的 cpp 文件,例如:

    #include "the_foo.h" 类 TheBar {};//TheBar 定义

    会编译得很好。然而,

  2. 任何包含 the_foo.hDOES 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/

相关文章:

c++ - 下面的C++语句是什么意思

c++ - C++ 标准库是否必须用 C 或汇编语言编写?

c++ - 无法访问 vc++10 中的模板私有(private)继承

css - 当菜单最后呈现时让博客文本环绕菜单 DIV

c++ - 为什么 term 不评估一个带 0 个参数的函数?

c++ - 关闭部分代码的优化

c++ - sizeof如何计算结构的大小

c++ - Visual Studio 2010 C++ 的调试问题 - 显示奇数​​值

c++ - 下面的代码是否应该按照 C++ 标准编译?

c++ - VS2010 : templates and overloaded functions 的解决方法