簡體   English   中英

包含在頭文件與前向聲明中,並包含在.cpp中

[英]Include in header file vs. forward-declare and include in .cpp

我有一個B類,我想把成員稱為A類。所以:

1。

//A.h    
class B; 
class A 
{ 
private:
    B* m_p; 
}; 

//a.cpp
#include "B.h"

2。

// A.h
#include "B.h"

class A 
{ 
private: 
    B * impl_; 
}; 

當一個沒有太多依賴性的小項目涉及時,這兩種方式是否更好?

你做的第一種方式意味着在ahclass B存在是已知的,但不是它的定義 這限制了你可以用B里面做什么ah 例如,您可以使用類型B *變量,但不能使用類型B變量(因為對於類型B的變量的聲明,編譯器必須能夠看到B的完整定義)。 此外,如果您有B *類型的變量,則不能取消引用指針(因為也必須知道B的定義)。

因此,您的第二選擇 - 沒有這些問題 - 是首選,這是大多數人在大多數時間使用的。

這是第一種方法可能有用的特殊情況。 例如:

  • 如果.h文件包含彼此 (但是你可能會遇到一些其他問題,也就是包含防范問題;這通常很難並且要避免);
  • 如果bh非常大且復雜,那么您希望盡可能避免包含它,因為它會降低編譯過程的速度。

你的第一種方法是前瞻性聲明。 你的第二個實際上包括B班。

何時使用一個而不是另一個?

使用第一個時:

  • 在A的定義中,您只有一個指向B的指針,即不是B的成員。
  • 你永遠不會從A的定義中調用B的任何函數。(即對B的成員函數的所有調用都發生在實際實現A的成員函數的.cpp文件中。)
  • 你希望B類的接口或大小經常改變,但不是A的接口。這樣,如果B改變,只有a.cpp的內容得到重新編譯,但啊(和其他包含啊的文件)不需要改變。

在以下情況下使用第二個:

  • 您需要知道B的大小 。編譯器使用其類定義及其所有成員的大小來計算類的大小。 例如,如果類A具有類型B的成員,那么為了計算A的大小,編譯器需要知道B的大小; 要知道B的大小,你需要包括bh
    • 你需要調用類B的函數。為了知道你是否正在調用實際存在的函數,編譯器需要知道B類的接口,即你需要包含bh

答案: 1
看看http://www.umich.edu/~eecs381/handouts/handouts.html

C頭文件指南

C ++頭文件指南 (密歇根大學EECS部門David Kieras)說:

准則#10。 如果X類型的聲明不完整,請使用它而不是#including其標題Xh 如果另一個結構或類類型X在標題文件的內容中僅作為指針或引用類型出現,那么您不應該#include Xh,而只是在附近放置一個不完整的X聲明(也稱為“前向”聲明)。標題文件的開頭,如: class X; 有關這種強大而有價值的技術的更多討論,請參閱講義不完整聲明 請注意,標准庫包含一個不完整聲明的標頭,通常用於<iostream>庫,名為<iosfwd> #include <iosfwd>盡可能,因為<iostream>標題文件非常大(巨型模板!)。

只需在類A的標題中聲明該類。

class B;

第二個更好。 它使B類成為您使用.h文件包含的模塊。 考慮將來子類化B並更新A以使用C 在第二種情況下,你只需要替換標題#includeA的化妝。 在第一種情況下,您必須更改前向聲明。 此外,在第二種情況下,您定義的不僅僅是符號B

和注釋一樣,如果頭文件與其余代碼位於同一目錄中,則應使用#include "Bh"

那么你正在做的事情被稱為前向解除,你想要的原因就是如果你有類A的東西使用類B和ALSO類B使用類A.

在只有一種關系的情況下,你當然可以使用你的第二選擇。 如果您需要雙重用法,那么至少有一個類的變換必須使用前向變換

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM