2014-07-25 90 views
0

我剛剛開始在C++中使用OOP,並且不斷收到「基類未定義錯誤」。我正在編寫一個基本上是一個庫的項目,但使用類。谷歌並沒有真正提供太多的幫助,因爲大多數時候,其他人發生的錯誤似乎是編寫自己的頭文件時的循環引用。基類是未定義的錯誤(C2504)

下面是程序(原諒贅言,我擠一切成一個文件暫時) driverLibrary.cpp:

#include "stdafx.h" 
#include <iostream> 
using namespace std; 

class LibraryItem :public Borrowable{ 
public: 
    LibraryItem(string name, int id) :identifier(name), id(id){} 
    LibraryItem(); 
    ~LibraryItem(); 
    string getIdentifier(){ 
     return identifier; 
    } 
    int getId(){ 
     return id; 
    } 
    bool borrow(){ return false; } 
    bool canBorrow() { return false; } 
    bool operator== (LibraryItem &comparison) 
    { 
     return (comparison.getId() == this->id); 
    } 
protected: 
    string identifier; 
    int id; 
}; 
class Borrowable{//interface 
public: 
    bool isIn; 
    virtual bool borrow() = 0; 
    virtual bool canBorrow() = 0; 
}; 
class Book :public LibraryItem, public Borrowable{ //all children will be borrowed the same way unless specified in their own class 
public: 
    Book(string name, int id, string author, string genre) :author(author), genre(genre){ LibraryItem(name, id); } 
    Book(string name, int id, string author){ LibraryItem(name, id); this->author = author; } 
    string getAuthor(){ return author; } 
    string getGenre(){ return genre; } 
    //override 
    bool borrow(){ 
     if (!isIn) return false; 
     else isIn = false; 
     return true; 
    } 
    bool canBorrow(){ return isIn; } 
protected: 
    string author; 
    string genre; 
    bool isIn;//override 
}; 
class Newspaper : public Media{ 
public: 
    Newspaper(string name, int id, int vol, int issue) : vol(vol), issue(issue){ LibraryItem(name, id); } 
    int getVol(){ return vol; } 
    int getIssue(){ return issue; } 
    bool borrow(){ 
     if (!isIn) return false; 
     else isIn = false; 
     return true; 
    } 
    bool canBorrow(){ return isIn; } 
protected: 
    int vol; 
    int issue; 
    bool isIn; 
}; 
class Reference : public Book{//, public Borrowable{ 
public: 
    Reference(string name, int id, string author, int vol, int issue, string topic) : vol(vol), issue(issue), topic(topic), Book(name, id, author){} 
    int getVol(){ return vol; } 
    int getIssue(){ return issue; } 
    // bool borrow(){ return false; } 
    // bool canBorrow(){ return false; } 
protected: 
    int vol; 
    int issue; 
    string topic; 
}; 
class Magazine : public Media, public Borrowable{ 
public: 
    Magazine(string name, int id, string title, string publisher, int date); 
}; 
class Media : public LibraryItem, public Borrowable{ 
public: 
    Media(string name, int id, string title, string publisher) : title(title), publisher(publisher), LibraryItem(name, id){} 
    bool borrow(){ 
     if (!isIn) return false; 
     else isIn = false; 
     return true; 
    } 
    bool canBorrow(){ return isIn; } 
protected: 
    string title; 
    string publisher; 
    bool isIn; 
}; 
class CD :public Media{ 
public: 
    CD(string name, int id, string title, string publisher, int length, string artist) :length(length), artist(artist), Media(name, id, title, publisher) {} 
    int getLength(){ return length; } 
    string getArtist(){ return artist; } 
protected: 
    int length; 
    string artist; 
}; 
class DVD : public Media{ 
public: 
    DVD(string name, int id, string title, string publisher, int dpi) : dpi(dpi), Media(name, id, title, publisher) {} 
    int getDPI(){ return dpi; } 
protected: 
    int dpi; 
}; 

int main() 
{ 
    Book book = Book("Identifier", 234, "Mike Hunt"); 
    return 0; 
} 

這裏是錯誤日誌:

Error 1 error C2504: 'Borrowable' : base class undefined c:\users\connor\documents\visual studio 2013\projects\consoleapplication2\consoleapplication2\driverlibrary.cpp 8 1 ConsoleApplication2 
Error 2 error C2504: 'Media' : base class undefined c:\users\connor\documents\visual studio 2013\projects\consoleapplication2\consoleapplication2\driverlibrary.cpp 53 1 ConsoleApplication2 
Error 3 error C2504: 'Media' : base class undefined c:\users\connor\documents\visual studio 2013\projects\consoleapplication2\consoleapplication2\driverlibrary.cpp 81 1 ConsoleApplication2 
    4 IntelliSense: no default constructor exists for class "Media" c:\Users\Connor\Documents\Visual Studio 2013\Projects\ConsoleApplication2\ConsoleApplication2\driverLibrary.cpp 55 77 ConsoleApplication2 
+0

只是聲明'類Borrowable' **'類LibraryItem'之前,並修正錯誤的下一串然後:P ... –

+0

啊,我們走吧。我想我應該爲其他可能有同樣問題的人留下線索? – user2073881

+0

我提到的還有更多的問題:'class Book:public LibraryItem,public Borrowable'你爲什麼要再次引入抽象類? 'LibraryItem'已經繼承了它。我猜猜還有其他一些問題。你的代碼看起來很詭異: -/...你的線程過於專業化/寬泛,對其他人有幫助。 –

回答

1

您需要在使用它們之前聲明(並在某些情況下定義)類。這就像C++中的變量,函數和其他任何東西一樣。

您應該可以通過將Borrowable的定義移動到文件頂部並將Media正確地放在LibraryItem之後來修復編譯器報告的前三個錯誤。

第四個錯誤是因爲Newspaper沒有明確調用構造函數Media,並且Media沒有編譯器可以插入調用的默認構造函數。

0

C++類型的可見性從它們首次被聲明的點開始延伸。順序很重要,它是C語言的繼承特徵,它基於包含文件的「文本」處理,而不是真正的模塊或多文件類型元數據,編譯器在傳統上將每種類型註釋爲句法聲明,並將其存儲在符號表,它立即可用。

這與Java或C#編譯器不同,後者首先解析整個源文件,然後再解析類型和符號,從等式中刪除順序。

爲了允許C++中的循環關係,有一個稱爲前向聲明的特性。它允許您將指針類型聲明爲尚未定義的類型(聲明的聲明與定義不同)。

class A; // declaration 

class B { 
    class A * a; // refers to A, but does not use any members within A yet 
}; 

class A { // definition 
    int size; 
};