2015-10-06 165 views
-1

我有下面的類(它基本上是std :: vector的包裝器),其中一個函數返回AInteger類型的變量(它基本上是一個int類型的包裝器)。現在AInteger類在整個類中被多次使用,但編譯器開始抱怨一個非常特定的位置。當我刪除「getSize()」函數時,一切都編譯得很好。前置聲明被忽略?

有相互包含,所以我需要前進宣言的一切工作。

其中一個問題是,AList類是一個模板,所以不可能將定義移動到.cpp文件(通常可以解決問題)。

我在做什麼錯?

這裏的類:

#ifndef ALIST_H 
#define ALIST_H 

#include <vector> 

#include "AInteger.h" 

class AInteger; 

template<typename VALUE> 
class AList { 
public: 
    AList() { 
    } 

    AList(const std::vector<VALUE> list) { 
     value = list; 
    } 

    ~AList() { 
    } 

    operator const std::vector<VALUE>() const { 
     return value; 
    } 

    std::vector<VALUE> toStdVector() const { 
     return value; 
    } 

    VALUE operator [](const AInteger index) const { 
     return value.at(index); 
    } 

    void add(const VALUE value) { 
     this->value.push_back(value); 
    } 

    VALUE get(const AInteger index) const { 
     return value[index]; 
    } 

    AInteger getSize() const { // ERROR OCCURS HERE 
     return value.size(); 
    } 

    void remove(const AInteger index) { 
     value.erase(index); 
    } 

private: 
    std::vector<VALUE> value; 
}; 

#endif 

輸出:

1>------ Build started: Project: ALibrary, Configuration: Debug Win32 ------ 
1> ASocket.cpp 
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
1> AInteger.cpp 
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
1> AHttpRequest.cpp 
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
1> ABoolean.cpp 
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
1> Generating Code... 
1> Compiling... 
1> AString.cpp 
1> Generating Code... 
2>------ Build started: Project: BitHoarder, Configuration: Debug Win32 ------ 
2> SystemHandler.cpp 
2>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
2> Main.cpp 
2>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
2> Generating Code... 
========== Build: 0 succeeded, 2 failed, 0 up-to-date, 0 skipped ========== 

如果需要更多的代碼,只是問,我會提供。

謝謝!

編輯: 下面是這裏面的「AInteger.h」

#ifndef AINTEGER_H 
#define AINTEGER_H 

#include "AList.h" 

template<typename VALUE> 
class AList; 

class AInteger { 
public: 
    AInteger(); 
    AInteger(const int); 
    ~AInteger(); 

    operator const int() const; 

    int toInt() const; 

    AInteger operator=(const AInteger &); 
    AInteger & operator++(); 
    AInteger & operator--(); 

    AList<AInteger>splitByNumber(const AInteger &); 

private: 
    int value; 
}; 

#endif 

使事情更加混亂,下面的類,它不完全一樣的事情不會產生錯誤的代碼:

#ifndef ADICTIONARY_H 
#define ADICTIONARY_H 

#include <map> 

#include "AInteger.h" 

class AInteger; 

template<typename KEY, typename VALUE, typename COMPARE = std::less<KEY>> 
class ADictionary { 
public: 
    ADictionary() { 
    } 

    ADictionary(const std::map<KEY, VALUE, COMPARE> dictionary) { 
     value = dictionary; 
    } 

    ~ADictionary() { 
    } 

    operator const std::map<KEY, VALUE, COMPARE>() const { 
     return value; 
    } 

    std::map<KEY, VALUE, COMPARE> toStdMap() const { 
     return value; 
    } 

    VALUE operator [](const KEY key) const { 
     return value.at(key); 
    } 

    void add(const KEY key, const VALUE value) { 
     this->value.insert(std::make_pair(key, value)); 
    } 

    VALUE get(const KEY key) const { 
     return value[key]; 
    } 

    AInteger getSize() const { // No error here 
     return value.size(); 
    } 

    void remove(const KEY key) { 
     value.erase(value.find(key)); 
    } 

private: 
    std::map<KEY, VALUE, COMPARE> value; 
}; 

#endif 
+2

是不是AInteger在 「AInteger.h」 聲明?如果是這樣,爲什麼包括後需要聲明? – vmg

+0

@vmg有相互包含,所以我需要轉發聲明,否則我會得到錯誤。 – Qub1

+1

轉發聲明不會神奇地消除相互包含。 – juanchopanza

回答

4

getSize()的執行必須創建一個AInteger的實例。這僅在已知AInteger的完整定義時纔可能。您不能創建只有前向聲明的類型的實例。

這正是編譯器告訴你的:error C2027: use of undefined type 'AInteger'。它不會忽略前向聲明,但告訴你,這是不夠的。

至於#include "AInteger.h",你不顯示其內容,但可能的問題是:

  • 巴吉包括在頭文件中後衛使編譯器跳過定義。
  • 頭文件定義了一個具有類似名稱的不同類型。
  • AInteger的定義在名稱空間內。
+0

好的,但爲什麼編譯器會忽略#include呢?它不應該有定義嗎?謝謝您的幫助! – Qub1

+0

@ Qub1:AInteger.h是否定義了類型? –

+0

那麼它包含了AInteger類及其函數的聲明,包括構造函數。所以我很困惑爲什麼編譯器會忽略所有這些。 – Qub1

2

問題出在Christian Hackl的答案中回答得很好,通常我會把它放在那裏,但我無法解釋OP如何在評論中正確解決這個問題。

首先修訂AInteger.h

#ifndef AINTEGER_H 
#define AINTEGER_H 

template<typename VALUE> 
class AList; 

class AInteger { 
public: 
    AInteger(); 
    AInteger(const int); 
    ~AInteger(); 

    //operator const int() const; 

    int toInt() const; 

    AInteger operator=(const AInteger &); 
    AInteger & operator++(); 
    AInteger & operator--(); 

    std::unique_ptr<AList<AInteger>> splitByNumber(const AInteger &); 
    void splitByNumber(const AInteger &, 
         AList<AInteger> &); 

private: 
    int value; 
}; 

#endif 

的包括AList.h已經一去不復返了。 AList的前向聲明仍然提供了兩種不同的splitByNumber方法。選一個。第一個創建並返回a pointer protected by a smart pointer。第二種方法和我的個人偏好,引用由調用者創建的AList。

這件事既不知道AList的內部工作,因爲他們關心的只是A)它存在和b)他們可以得到一個地址。

在我探索這兩者的同時忍受着我,因爲我認爲它們都是教育性的。

除了刪除前向聲明AInteger之外,Alist.h保持不變。

兩個splitByNumber候選人坐在AInteger的執行文件,它可以安全地包括AInteger.h和AList.h,從而在同一時間既具有完整的知識,可以做所有的神奇的東西AIntegersALists可以做。

std::unique_ptr<AList<AInteger>> AInteger::splitByNumber(const AInteger & integer) 
{ 
    std::unique_ptr<AList<AInteger>> listp(new AList<AInteger>()); 

    // do stuff with listp 
    return listp; 
} 

void AInteger::splitByNumber(const AInteger & integer, 
          AList<AInteger> & list) 
{ 
    // do stuff with list 
} 

使用指針版本:

std::unique_ptr<AList<AInteger>> alistp = aitest1.splitByNumber(aitest2); 
alistp->add(somenumber); 

使用參考版本:

AList<AInteger> alist; // first create an empty AList 
aitest1.splitByNumber(aitest2, alist); // pass it into the function 
alist.add(somenumber); // use the AList