2016-10-27 52 views
1

所以我在下面的文件,其內容如下:類中需要類型的信息,這不是實際使用該類型

啊:

#ifndef A_H 
#define A_H 

class A { 
}; 

#endif 

BH:

#ifndef B_H 
#define B_H 

#include <memory> 

class A; 

class B { 
public: 
    B(std::unique_ptr<A> a); 
private: 
    std::unique_ptr<A> a_; 
}; 
#endif 

b.cpp:

#include "b.h" 
#include "a.h" 

B::B(std::unique_ptr<A> a) : a_(std::move(a)) { 
} 

ch :

#ifndef C_H 
#define C_H 

#include "b.h" 

class C { 
public: 
    void add_b(std::unique_ptr<B> b); 

private: 
    std::unique_ptr<B> b_; 
}; 

#endif 

c.cpp:

#include "c.h" 

void C::add_b(std::unique_ptr<B> b) { 
    b_ = std::move(b); 
} 

和含有空主要方法的文件。正如你在b.h中看到的,我實際上並不包括a.h,因爲我只在類聲明中使用了指針,這不是必需的,只有一個聲明就足夠了 - class A;。如果我嘗試編譯這個使用gcc我得到,指出類似的錯誤:

In file included from /usr/include/c++/5/memory:81:0, from b.h:4, from c.h:4, from c.cpp:1: error: invalid application of ‘sizeof’ to incomplete type ‘A’
static_assert(sizeof(_Tp)>0

當我看到「不完全類型‘A’」的一部分,我想通了,class C大概需要A更多信息,因爲它不知道它的存在,因爲它只包含b.h,它只使用A的聲明(class A;)。很明顯包括a.h頭文件在c.cpp解決了這個錯誤,但後來我才意識到A實際上並沒有參與C類的可見執行。爲什麼C需要了解更多關於class A的信息?究竟發生了什麼?我認爲這很難理解,難以遵循。我怎樣才能避免這種情況?原來的例子更加複雜,所以我不得不挖掘並簡化它。我只是想要一個只有必要信息的最小頭文件,避免不必要的宏擴展。

回答

2

but then I realized that A is not actually involved in the visible implementation of C class. Why does C need to know more info about class A?

class A需要如在class C

std::unique_ptr<B> b_; 

需要,因此誤差將與的class B實施看出。

通過class Bpublic部分可以看到A並不重要。 class B必須在該點完全申報,其中包括輪流申請class A的完整申報。

0

由於std :: unique_ptr是底層不完整類型A的大小,顯示錯誤。顯然,要獲取類型的大小,必須定義類型。

unique_ptr是基礎類型大小的原因是因爲std::default_delete<A>。如果覆蓋unique_ptr的默認刪除器,則可以將其設置爲不覆蓋基礎類型的大小,並且可以在不完成類型的情況下進行編譯。

示例...

#include <memory> 
#include <iostream> 

class A; 

struct Deleter { 
    void operator()(A* ptr) const { 
     std::cout << "I'm supposed to delete A but I'm a liar!" << std::endl; 
    } 
}; 

int main() { 
    std::unique_ptr<A, Deleter> a(reinterpret_cast<A*>(1)); 
} 

這編譯,鏈接和運行得很好

+0

它編譯罰款 - 但現在它基本上只是一個'*'。 – Barry

+0

這正是他的問題所在。他問他爲什麼只使用指針時會出現不完整的類型錯誤......這正是原因。 – pat

相關問題