2013-02-20 42 views
0

我有一個項目,我不得不從具有.cpp /頭文件分離到只將頭文件加入定義。我試圖最初將cpp文件的內容複製到頭文件中,但是我的ide - VS2012 express - 發送給我一個循環,它表示頭文件包含它自己,所以當我刪除包含「class.h」時,它抱怨說在Class :: functionname的情況下,Class不能被識別。最後,我決定在標題定義的定義本身例如僅C++頭文件項目 - 使用不同的程序集

class Thing { 
public: 
    void func { code; } 
} 

這固定在我的項目編譯的問題。麻煩的是我有一個測試項目 - WinUnit - 我無法再訪問這些函數。該項目曾經是一個靜態庫,並相應鏈接,但因爲沒有.cpp文件,該項目沒有生成.lib文件。試圖改變到動態鏈接庫,同樣的問題 - 沒有DLL生產。所以我添加了一個項目引用,它似乎起作用,因爲它在我輸入#include「Class.h」時識別了我的類文件。

我的問題是它仍然不編譯類。它根本無法識別測試項目的.cpp文件中的類名。我甚至嘗試將頭文件添加到測試項目中,但仍然沒有喜悅。我嘗試設置其他包含目錄來指向標頭的位置 - 沒有用。

我該如何做到這一點?

編輯: 仍然卡住了,所以我創建了一個SSCCE,它工作正常,將測試項目指向Additonal INclude目錄中的頭文件目錄,它工作正常。雖然主要項目編譯好,我注意到它有一個intellisense錯誤 - 標識符「ClassName」未定義。其他所有類都可以識別其他類。 #include「className」存在。當我構建測試項目時,第一個錯誤與此行與智能感知錯誤相關:錯誤1錯誤C2143:語法錯誤:缺少';'在'*'之前

實際的行是:ClassName * obj; - 這是一個私人變量。

測試項目中有629個錯誤 - 其他代碼:c4430,c2061。我猜這些只是最初的問題相關的類沒有被識別的副作用...我失去了,可能退縮,並重新考慮失敗這....

編輯:修復intellisense錯誤,所以所有的錯誤都在測試項目現在 - 上升到826錯誤。在包含它們時查看頭文件,但不能識別任何類名。錯誤代碼:c2061,c2065,c2923等

+2

爲什麼你想從一個精心打造的項目轉移到只有頭部的項目? – 2013-02-20 09:40:40

+0

爲了使用SDK,但現在我發現了一個備用解決方案,所以已經回滾了! – 2013-02-21 20:48:57

回答

1

在您的示例代碼func是私有的,因爲這是一個類中的默認訪問。也許你想定義公開的功能,使其可以用於你的測試代碼和其他類的客戶端。

如果您只是將函數定義放入頭文件中,您還必須將它們內聯。顯式地(對於自由函數和完全專用的函數模板定義),或者隱式地,即在類定義內部定義類方法。

你是對的,該庫不再產生任何編譯的輸出,即你不得不鏈接一個lib或dll文件。因此,在任何使用該庫的項目(包括測試項目)中,不再需要指定要與該項目鏈接的庫。畢竟,這是僅有頭文件庫的原因之一:它們在編譯時完全包含在內(而不是鏈接時間)。

如果您的測試項目之前編譯過,它應該在修改後編譯,前提是您之前已經測試了所有庫類,並且沒有對命名空間結構進行任何更改。

如果沒有SSCCE以及從編譯器獲得的適當錯誤,只能猜測您可能遇到的其他問題。

編輯:即使源頭到頭重構已正確完成,也會引起麻煩的一件事是循環包含。如果你有這些,你就必須要麼打破依賴或者把兩個類在同一個頭,兩個類定義後提供方法定義(記得行內顯式聲明的方法定義)

EDIT2:爲簡單的例子一個循環包含:A和B類都有一個調用另一個類的方法。因此,每個類方法的定義需要其他類方法的聲明,即其他類的前向聲明是不夠的。在正常情況下,來源將包括標題和完成。在僅郵件頭的情況會是這樣的編譯器:

class A { 
    B* b_; 
public: 
    A(B* b) : b_(b) {} 
    void foo() {b_->meow();} 
}; 

class B { 
public: 
    void bar() { A a(this); a.foo(); } 
    void meow() { /* ... */} 
}; 

編譯器會抱怨B的使用和調用B::meow()。前者可以通過前向聲明B來解決,後者不能。先定義B不會有幫助,但你會遇到與A和A::foo()相同的問題。因此,解決方案必須是這樣的:

class A { 
    B* b_; 
public: 
    A(B* b) : b_(b) {} 
    void foo(); //1 
}; 

class B { 
public: 
    void bar() { A a(this); a.foo(); } 
    void meow() { /* ... */} 
}; 

inline void A::foo() {b_->meow();} //2 

第一類的定義依賴於第二類萬畝方法被推遲,直到第二下課的定義。由於A需要B和B需要A,因此在僅用於標題的庫中將兩個不同標題中的混合類定義分開是沒有意義的。

分離這些東西的一種方法是打破依賴關係。在上述情況下,可能是這樣的:

class B_Interface 
{ 
public: 
    virtual void meow() = 0; 
}; 

class A { 
    B_Interface* b_; 
public: 
    A(B_Interface* b) : b_(b) {} 
    void foo() {b_->meow();} //OK this time 
}; 

class B : public B_Interface { 
public: 
    void bar() { A a(this); a.foo(); } 
    virtual void meow() { /* ... */} 
}; 

這是以一個更間接的成本,但分隔兩班的依賴,使人們能夠更容易等測試

+0

對不起,關於示例代碼,我忘了說他們是在「public:」修飾符下定義的。我試着明確地把公開課變成公開課。我會嘗試一個SSCCE未能儘快解決任何建議。 – 2013-02-20 09:48:59

+0

'公共類'是Java或C#或其他,而不是C++。我將編輯修改器到您的示例代碼中。但是,除了你之外,沒有人知道你的代碼實際上是什麼樣的,所以*沒人知道問題可能是什麼。 – 2013-02-20 09:51:21

+0

感謝Arne,我拿出了「公共類」的東西,但「public:」修飾符正確 – 2013-02-20 09:53:36

0

我有足夠的,由於某種原因,它仍然無法正常工作,這是浪費我的時間和精力。我回到一個構建良好的項目,只有頭文件。

相關問題