2015-11-27 167 views
3

我遇到了以下錯誤 - 當我只是先提供類的定義,然後再聲明它。我的理解是,只要我們這樣做,因爲我已經做了很多次函數定義,編譯器得到它,但似乎我的理解是有缺陷的,有人可以幫助我理解理解如何聲明類的缺失部分。錯誤C2027:使用未定義的類型 - 如何聲明類

error C2027: use of undefined type 'generic_iterator' 
note: see declaration of 'generic_iterator 

不工作 - 上述

#include <iostream> 
class generic_iterator; 
class darray 
{ 
public: 
    typedef generic_iterator iterator; 
    darray(); 
    darray(int size); 
    ~darray(); 
    int& at(int index); 
    int& operator [](int i); 
    int* data(void); 
    bool empty(); 
    void fill(int val); 
    void print(); 
    size_t max_size(); 
    iterator begin() {return iterator(ptrarray); } 
    iterator end() { return iterator(ptrarray + size); } 

private: 
    int *ptrarray; 
    int num_elements; 
    int size; 
}; 

class generic_iterator 
{ 
public: 
    generic_iterator(int *ptr); 
    ~generic_iterator(); 
    generic_iterator& operator++();  // pre-increment 
    generic_iterator operator++(int); // post-increment 
private: 
    int *iptr; 
}; 

作品顯示錯誤:當整個類被聲明爲第一

class generic_iterator 
{ 
public: 
    generic_iterator(int *ptr); 
    ~generic_iterator(); 
    generic_iterator& operator++();  // pre-increment 
    generic_iterator operator++(int); // post-increment 
private: 
    int *iptr; 
}; 

class darray 
{ 
public: 
    typedef generic_iterator iterator; 
    darray(); 
    darray(int size); 
    ~darray(); 
    int& at(int index); 
    int& operator [](int i); 
    int* data(void); 
    bool empty(); 
    void fill(int val); 
    void print(); 
    size_t max_size(); 
    iterator begin() {return iterator(ptrarray); } 
    iterator end() { return iterator(ptrarray + size); } 

private: 
    int *ptrarray; 
    int num_elements; 
    int size; 
}; 

回答

2

當你在使用它之前聲明一個東西的摘要,這就是所謂的聲明

向一個函數進行前向聲明時,編譯器具有它需要的所有東西來解析調用該函數的代碼:函數的名稱,返回的類型,參數的數量以及每個參數的類型。

但是,當向一個類進行前向聲明時,編譯器只知道這個特定的符號(在你的情況下是generic_iterator)是一個類。隨後,在完全定義它之前,你可以用它做的唯一事情就是聲明一個指針。 (和我有更多C++知識的人可能會知道一兩個額外的奧術用途。)你不能調用它的任何成員,因爲編譯器還不知道它的結構。你的代碼試圖調用你的前向引用類的構造函數,但編譯器還不知道任何這樣的構造函數。

我不知道任何簡單的方法來解決這個問題。其他人可能有一些更好的解決方案,但我傾向於解決此問題的方式是將需要訪問前向聲明類的成員的所有代碼從.h文件移動到.cpp文件。所以,在你的情況下,在.h文件中,我只會寫iterator begin();,然後在.cpp文件中,我會寫generic_iterator darray::begin() {return iterator(ptrarray); }

這會編譯,因爲那時候已知完整的類定義generic_iterator

+0

謝謝你的回答和糾正我的行話 - 那麼工作方式只是方法來解決錯誤 - 或者在這種情況下還有其他方式來聲明前向聲明? – ifelse

+0

@ifelse我修改了我的答案。 –

+1

啊哈!我現在通常使用.cpp聲明,這次我聲明它是內聯的,而且我遇到了錯誤。我想現在我更好了..感謝很多! – ifelse

3

編譯器需要知道類的定義generic_iterator這是解析這些函數定義

iterator begin() {return iterator(ptrarray); } 
iterator end() { return iterator(ptrarray + size); } 

否則無法確定此代碼是否正確,即類generic_iterator是否具有可用一個參數調用的構造函數。

考慮到將常數下標運算符與非常數運算符一起聲明是正確的。例如

int& operator [](int i); 
const int& operator [](int i) const; 

int& operator [](int i); 
int operator [](int i) const; 

也嘗試使用預選賽const與成員函數不改變物體本身例如像emptymax_size也許print

bool empty() const; 
void print() const; 
size_t max_size()const; 
+0

感謝關於類的其他功能的指針 - 所以我已經顯示的片段的工作方式,這將是唯一的方式來聲明類,即在其他類中使用它之前完全定義它 - 或我需要牢記一些其他形式的前瞻性聲明? – ifelse

+0

@ifelse您可以在迭代器的類定義之後,在類定義之外定義這些函數(它們將只在類定義中聲明)。 –

+0

明白了 - 謝謝! – ifelse

相關問題