2012-03-19 49 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