2012-03-19 74 views
0

我的教授給了我們這門課,並告訴我們它不會編譯。他表示捐助者陣列會與構造者發生衝突。所以...爲什麼會這樣呢?這個類的C++聲明有什麼問題?

我認爲Donor陣列的名稱可能做到這一點,但由於成員數組donor的名稱是區分大小寫,因此比類名不同,應該不是問題。

下面的代碼:

#ifndef DONORS_H 
#define DONORS_H 

#include <string> 

#include "name.h" 
#include "donor.h" 

using namespace std; 

const int 
    DONORS_LOAD_ERROR = 1, 
    DONORS_UPDATE_ERROR = 2, 
    DONORS_ADD_ERROR = 3; 

const int MAX_DONORS = 100; 

class Donors { 
public: 
    Donors() : size(0) {} 
    void load(string filename); 
    int getSize() {return size;} 
    int find(Name name); 
    int add(Name name); 
    int add(Name name, Donation donation, int ytd); 
    void processDonation(Name name, Donation donation); 
    void update(string filename); 
    void print(); 
private: 
    Donor donorsList[MAX_DONORS]; 
    int size; 
}; 

#endif 

教授寫道:

在這個版本中,我們已經採取了第2版,添加構造函數,並最大限度地利用對象。

然而,引入構造函數會破壞Donors類中數組數據成員的聲明; 因此這個版本不編譯!

我一直在和同學討論這件事,我們都很難過。這個C++類是什麼?

編輯:

編譯器的消息如下:

Compiler Error

它只是發生在我身上的捐贈類有一個構造函數。因爲我們沒有觸及十腳的矢量,我們究竟應該怎樣編譯這個?

EDIT2:

這裏的施主類:

#ifndef DONOR_H 
#define DONOR_H 

#include "name.h" 
#include "donation.h" 

using namespace std; 

class Donor { 
public: 
    Donor(Name n, Donation ld=Donation(0, 0), int y=0) : name(n), lastDonation(ld), ytd(y) {} 
    Name getName() {return name;} 
    Donation getLastDonation() {return lastDonation;} 
    int getYtd() {return ytd;} 
    void processDonation(Donation d); 
private: 
    Name name; 
    Donation lastDonation; 
    int ytd; 
}; 

#endif 
+1

「不會編譯」 是不夠的錯誤描述,你知道的。 – Griwes 2012-03-19 17:17:10

+1

當你試圖編譯它時,你得到了什麼錯誤信息? – 2012-03-19 17:17:32

+2

編譯錯誤是什麼? – octal9 2012-03-19 17:17:39

回答

5

難而不Donor類的定義說,但我的猜測是,他增加了一個構造函數參數的Donor類,所以它不會再有隱式的默認構造函數。

但是現在,沒有默認構造函數,這是一個可以不帶參數調用的構造函數,因此無法聲明這種類型的數組,因爲沒有辦法傳遞所需的參數!

+0

您的預感是正確的:http://chat.stackoverflow.com/transcript/message/2990667#2990667。 – sbi 2012-03-19 17:26:47

3

我的猜測是類Donor(你沒有包括)沒有默認的構造函數。如果是的話,你會得到一個編譯錯誤,因爲這條線:

Donor donorsList[MAX_DONORS]; 

將嘗試使用構造與 - 無參數Donor沒有。

如果您遇到您的導師向您展示的錯誤,它將幫助您在課程中做得更好。那麼當你在現實生活中遇到他們時,你會認出他們。如果你要學習C++,那麼「我和朋友看着這個並且應該編譯好」的策略永遠不會成爲嘗試編譯它並查看你得到什麼錯誤的替代品。

+0

你的預感是正確的:http://chat.stackoverflow.com/transcript/message/2990667#2990667。 – sbi 2012-03-19 17:25:59

0

您需要包含class Donor的定義。

從外觀上看,我猜class Donor有一個非默認構造函數,即i。即構造函數接受一個或多個參數。在這種情況下,編譯器不會生成class Donor的默認構造函數,您必須自己定義它。

創建donorsList需要默認構造函數,因爲當您創建一個對象數組時,將爲每個對象調用默認的構造函數。

0

首先考慮Donors類:

#ifndef DONORS_H 
#define DONORS_H 

#include <string> 

#include "name.h" 
#include "donor.h" 

OK爲止。

using namespace std; 

不!永遠不要將using namespace std;放在標題中的全局名稱空間中。作者(你的教授)幾乎可以保證愚蠢的名字衝突,比如編譯器在一些不好的用戶’的代碼中抱怨distance

const int 
    DONORS_LOAD_ERROR = 1, 
    DONORS_UPDATE_ERROR = 2, 
    DONORS_ADD_ERROR = 3; 

const int MAX_DONORS = 100; 

這些都是壞名字。保留呼籲所有大寫的宏名稱。但是,請將它們用於宏名稱。

此外,最好使用enum這樣的常數。

此外,還可以更好地使用異常來進行故障報告。

class Donors { 
public: 
    Donors() : size(0) {} 
    void load(string filename); 

string參數會更好通過引用傳遞給const

int getSize() {return size;} 

該方法應該是const

此外,雖然前綴get在一些語言如Java和C#,支持instrospection(因此基於內省工具)的實際優勢,在C++中,它只是愚蠢的冗長–在大多數情況下,在這種情況下。

更好地調用該方法只需name

準則:考慮調用代碼的可讀性。

int find(Name name); 

name說法可能會更好,因爲參考const傳遞。

int add(Name name); 

name說法可能會更好,因爲參考const傳遞。

int add(Name name, Donation donation, int ytd); 

namedonation參數可能會更好,因爲到const引用傳遞。

名稱ytd非常糟糕。猜測它的含義是非常困難的。

void processDonation(Name name, Donation donation); 

namedonation參數可能會更好,因爲到const引用傳遞。

界面不明確:addprocess有什麼區別?

void update(string filename); 

name說法可能會更好,因爲參考const傳遞。

這種方法的名稱很糟糕。

幾乎不可能猜到這個方法做了什麼。

void print(); 

這個方法究竟應該在哪裏打印什麼,以什麼格式?

private: 
    Donor donorsList[MAX_DONORS]; 

這個聲明要求Donor有一個構造函數可以不帶參數調用,一個默認構造函數

int size; 
}; 

#endif 

考慮到第二Donor類:

#ifndef DONOR_H 
#define DONOR_H 

#include "name.h" 
#include "donation.h" 

OK爲止。

using namespace std; 

不!永遠不要將using namespace std;放在標題中的全局名稱空間中。作者(你的教授)幾乎可以保證愚蠢的名字衝突,比如編譯器在一些不好的用戶’的代碼中抱怨distance

class Donor { 
public: 
    Donor(Name n, Donation ld=Donation(0, 0), int y=0) : name(n), lastDonation(ld), ytd(y) {} 

yytd是壞的名字。現在不可能猜到他們’是關於什麼的。

ld是個不好的名字。

NameDonation參數應該可能更好地通過參考const來傳遞。

注意:當有一個用戶聲明的構造函數,比如上面的那個,那麼默認的構造函數不會自動生成

Name getName() {return name;} 

該方法應該是const

此外,雖然前綴get在一些語言如Java和C#,支持instrospection(因此基於內省工具)的實際優勢,在C++中,它只是愚蠢的冗長–在大多數情況下,在這種情況下。

更好地調用該方法只需name

準則:考慮調用代碼的可讀性。

Donation getLastDonation() {return lastDonation;} 

請參閱上面的註釋。

int getYtd() {return ytd;} 

請參閱上面的註釋。

void processDonation(Donation d); 

該參數應該最好通過參考const來傳遞。

private: 
    Name name; 
    Donation lastDonation; 
    int ytd; 
}; 

#endif 

總之,Donors類需要Donor有一個默認的構造函數,但由於Donor具有不產生默認構造方法的用戶聲明的構造。

一種修復方法是用std::vector或其他集合取代簡單陣列,例如,

std::vector<Donor> donors_; 

std::map< std::string, Donor > donors_; 
+0

'捐助者'是我認爲'捐贈者'對象的容器。 – 2012-03-19 18:21:20

+0

呵呵,名字的細微差別。我沒有看到。讓我解決答案。 OK完成。 – 2012-03-19 18:32:34