C++ 什么';这类C&x2B有什么问题+;宣言?

C++ 什么';这类C&x2B有什么问题+;宣言?,c++,class,C++,Class,我的教授给我们上了这门课,告诉我们它不会编译。他说捐助者数组将与构造函数冲突。所以为什么会这样 我认为捐赠者数组的名称可以做到这一点,但这不应该是问题,因为成员数组捐赠者的名称区分大小写,因此与类名不同 代码如下: #ifndef DONORS_H #define DONORS_H #include <string> #include "name.h" #include "donor.h" using namespace std; const int DONORS_

我的教授给我们上了这门课,告诉我们它不会编译。他说捐助者数组将与构造函数冲突。所以为什么会这样

我认为
捐赠者
数组的名称可以做到这一点,但这不应该是问题,因为成员数组
捐赠者
的名称区分大小写,因此与类名不同

代码如下:

#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

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


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

我猜类
捐赠者
(您没有包括)没有默认构造函数。如果是这样,您将得到一个编译器错误,因为这一行:

Donor donorsList[MAX_DONORS]; 
将尝试在没有
Donor
没有参数的情况下使用构造函数


如果你经历了导师向你展示的错误,这将有助于你在课程中做得更好。然后,当你在现实生活中经历它们时,你会认出它们。如果你要学习C++,“我和朋友看这个,它应该编译好”的策略永远不会成为编译它和看到你得到什么错误的替代品。

< p>你需要包括“代码>类供体< /C> >的定义。< /P> 从外观上看,我猜
类捐助者
有一个非默认构造函数,即。E接受一个或多个参数的构造函数。在这种情况下,
类施主
的默认构造函数不是由编译器生成的,您必须自己定义它


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

考虑第一个
捐赠者
类:

#ifndef DONORS_H
#define DONORS_H

#include <string>

#include "name.h"
#include "donor.h"
#ifndef DONOR_H
#define DONOR_H

#include "name.h"
#include "donation.h"
从不使用命名空间std放置
。作者(你的教授)几乎保证了愚蠢的名字冲突,就像编译器抱怨某个糟糕用户代码中的
距离一样

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

const int MAX_DONORS = 100;
class Donor {
public:
    Donor(Name n, Donation ld=Donation(0, 0), int y=0) : name(n), lastDonation(ld), ytd(y) {}
这些都是坏名声。保留宏名称的所有大写字母。但一定要将它们用作宏名称

此外,最好对此类常量使用
enum

此外,更好地使用异常进行故障报告

class Donors {
public:
    Donors() : size(0) {}
    void load(string filename);
string
参数最好通过引用
const
传递

    int getSize() {return size;}
    int add(Name name);
    int add(Name name, Donation donation, int ytd);
private:
    Name name;  
    Donation lastDonation;
    int ytd;
};

#endif
此方法应为
const

    int getSize() {return size;}
    int add(Name name);
    int add(Name name, Donation donation, int ytd);
private:
    Name name;  
    Donation lastDonation;
    int ytd;
};

#endif

也可以,而前缀GET在java和C语言等语言中有实际的优势,它支持C++的内部设置(因此基于内省),它只是愚蠢的冗长-在大多数情况下,在这种情况下。 最好把那个方法叫做

name

准则:考虑调用代码的可读性

    int find(Name name);
    Donation getLastDonation() {return lastDonation;}
name
参数最好作为
const
的引用传递

    int getSize() {return size;}
    int add(Name name);
    int add(Name name, Donation donation, int ytd);
private:
    Name name;  
    Donation lastDonation;
    int ytd;
};

#endif
name
参数最好作为
const
的引用传递

    int getSize() {return size;}
    int add(Name name);
    int add(Name name, Donation donation, int ytd);
private:
    Name name;  
    Donation lastDonation;
    int ytd;
};

#endif
name
generation
参数最好作为
const
的引用传递

    int getSize() {return size;}
    int add(Name name);
    int add(Name name, Donation donation, int ytd);
private:
    Name name;  
    Donation lastDonation;
    int ytd;
};

#endif
名称
ytd
非常糟糕。很难猜出它的意思

    void processDonation(Name name, Donation donation);
name
generation
参数最好作为
const
的引用传递

    int getSize() {return size;}
    int add(Name name);
    int add(Name name, Donation donation, int ytd);
private:
    Name name;  
    Donation lastDonation;
    int ytd;
};

#endif
界面不明确:
add
process
之间有什么区别

    void update(string filename);
name
参数最好作为
const
的引用传递

    int getSize() {return size;}
    int add(Name name);
    int add(Name name, Donation donation, int ytd);
private:
    Name name;  
    Donation lastDonation;
    int ytd;
};

#endif
此方法的名称不正确

几乎不可能猜测这种方法的作用

    void print();
这个方法到底应该在哪里打印,以什么格式打印

private:
    Donor donorsList[MAX_DONORS];
此声明要求
Donor
具有一个可以无参数调用的构造函数,一个默认构造函数

    int size;
};

#endif

考虑到第二类捐赠者:

#ifndef DONORS_H
#define DONORS_H

#include <string>

#include "name.h"
#include "donor.h"
#ifndef DONOR_H
#define DONOR_H

#include "name.h"
#include "donation.h"
好的,到目前为止

using namespace std;
using namespace std;
从不使用命名空间std放置
。作者(你的教授)几乎保证了愚蠢的名字冲突,就像编译器抱怨某个糟糕用户代码中的
距离一样

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

const int MAX_DONORS = 100;
class Donor {
public:
    Donor(Name n, Donation ld=Donation(0, 0), int y=0) : name(n), lastDonation(ld), ytd(y) {}
y
ytd
都是坏名字。在这一点上不可能猜出他们在说什么

ld
是个坏名字

Name
generation
参数最好通过引用
const
传递

    int getSize() {return size;}
    int add(Name name);
    int add(Name name, Donation donation, int ytd);
private:
    Name name;  
    Donation lastDonation;
    int ytd;
};

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

此方法应为
const

    int getSize() {return size;}
    int add(Name name);
    int add(Name name, Donation donation, int ytd);
private:
    Name name;  
    Donation lastDonation;
    int ytd;
};

#endif

也可以,而前缀GET在java和C语言等语言中有实际的优势,它支持C++的内部设置(因此基于内省),它只是愚蠢的冗长-在大多数情况下,在这种情况下。 最好把那个方法叫做

name

准则:考虑调用代码的可读性

    int find(Name name);
    Donation getLastDonation() {return lastDonation;}
见上面的评论

    int getYtd() {return ytd;}
    void processDonation(Donation d);
见上面的评论

    int getYtd() {return ytd;}
    void processDonation(Donation d);
参数最好通过引用
const
传递

    int getSize() {return size;}
    int add(Name name);
    int add(Name name, Donation donation, int ytd);
private:
    Name name;  
    Donation lastDonation;
    int ytd;
};

#endif

简而言之,
Donor
类要求
Donor
具有默认构造函数,但由于
Donor
具有用户声明的构造函数,因此不会生成默认构造函数

一种修复方法是将简单数组替换为
std::vector
或其他集合,例如

std::vector<Donor> donors_;
std::向量捐赠者;

<代码