[英]Proper use of undefined type in template class inheriting from abstract class
我有一個頭文件(例如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" class TheBar {}; // TheBar definition
將編譯就好了。 然而,
任何包含the_foo.h和NOT DEFINE TheBar
cpp文件,例如:
#include "the_foo.h"
編譯失敗並出現錯誤: the_foo.h(11): error C2027: use of undefined type 'TheBar'
上面編譯的cpp文件僅包含一行:包含標題,沒有更多代碼。
刪除虛擬成員函數聲明virtual size_t bar_size() = 0;
確實解決了錯誤。
感謝Sam Varshavchik的回答,此代碼可以使用gcc 5.3.1很好地進行編譯,因此,此問題顯然是特定於編譯器的。
我的問題是:
TheBar
向前聲明TheBar
時,為什么在情況(2)中編譯失敗? 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 ++編譯器無法正確編譯”。
當您嘗試在Foo
類的構造函數和析構函數中構造或刪除class TheBar
時,編譯器會搜索class TheBar
的定義。 這意味着它需要那時的實現,否則它不知道該怎么做。
如果使用以下示例:
第一個標頭:
// foobase.h
class FooBase
{
public:
FooBase() {}
virtual ~FooBase() {}
};
template<class Bar>
class Foo : public FooBase
{
public:
Foo() { bar = new Bar; }
~Foo() { delete bar; }
private:
Bar* bar;
};
class TheBar;
class TheFoo : public Foo<TheBar>
{
public:
TheFoo() {};
~TheFoo() {};
};
下一個標題
// thebar.h
class TheBar {};
和以下主文件:
// foo_main.cxx
// #include "thebar.h" // Including this include makes the program run
#include "foobase.h"
int main()
{
TheFoo thefoo;
return 0;
}
然后,您的編譯器會告訴您哪里出了問題(僅顯示第一個錯誤):
./foobase.h:14:32: error: allocation of incomplete type 'TheBar'
Foo() { bar = new Bar; }
包括thebar.h
將解決問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.