这个类C ++声明有什么问题?

时间:2012-03-19 17:15:28

标签: c++ class

我的教授给了我们这堂课,并告诉我们它不会编译。他说,捐赠者阵列会与构造者发生冲突。那么......为什么会这样?

我认为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

我刚刚想到Donor类有一个构造函数。因为我们没有用十英尺的极点触及矢量,我们究竟应该如何编译它?

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

4 个答案:

答案 0 :(得分:5)

如果没有Donor类的定义很难说,但我的猜测是他在Donor类中添加了一个带参数的构造函数,因此它不再具有隐式默认构造函数

但是现在,如果没有默认构造函数,那是一个可以不带参数调用的构造函数,就不能声明这种类型的数组,因为没有办法传递所需的参数!

答案 1 :(得分:3)

我猜是类Donor(你没有包含)没有默认的构造函数。如果是这样,您将收到编译器错误,因为这一行:

Donor donorsList[MAX_DONORS]; 

将尝试使用Donor没有的构造函数 - 无参数。

如果您遇到教师向您展示的错误,它将帮助您在课程中做得更好。然后,当你在现实生活中体验它们时,你会认出它们。如果你要学习C ++,那么“我和一个朋友看过这个并且应该编译得很好”的策略永远不会替代尝试编译它并看到你得到的错误。

答案 2 :(得分:0)

您需要包含class Donor的定义。

从它的外观来看,我猜想class Donor有一个非默认的构造函数,i。即带有一个或多个参数的构造函数。在这种情况下,编译器不会生成class Donor的默认构造函数,您必须自己定义它。

创建donorsList需要默认构造函数,因为在创建对象数组时,会为每个对象调用默认构造函数。

答案 3 :(得分:0)

考虑第一个Donors类:

#ifndef DONORS_H
#define DONORS_H

#include <string>

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

目前为止确定。

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#)中具有实际优势,这些语言支持自省(因此基于内省的工具),但在C ++中,它只是愚蠢的冗长 - 在大多数情况下,并且在这种情况。

最好称之为mathod 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"

目前为止确定。

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是个坏名字。

最好通过引用Name来传递Donationconst参数。

注意:当存在用户声明的构造函数(例如上面的构造函数)时,默认构造函数不会自动生成

    Name getName() {return name;}

此方法应为const

此外,虽然前缀get在某些语言(例如Java和C#)中具有实际优势,这些语言支持自省(因此基于内省的工具),但在C ++中,它只是愚蠢的冗长 - 在大多数情况下,并且在这种情况。

最好称之为mathod 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_;