一、题目描述(略)
二、解题思路
①定义书本类,数据成员有书名、单价、出版社,静态数据成员有总价、总书本数、书价平均值,成员函数有带部分默认值的构造函数、不带默认值的构造函数、析构函数、复制函数、输出数据成员函数、修改数据成员函数、静态成员函数
②类外初始化静态成员,类外定义部分成员函数
③主函数定义数组复制已定义的对象
④测试是否创建对象成功、是否复制成功、未调用静态成员函数是否静态数据成员会改变、全传参对象、部分传参对象、不传参对象
⑤使用string类定义字符串
三、运行结果
四、代码
#include<iostream>
#include<string>
using namespace std;
class xh_book//新华的书
{
private:
string b_name;//书名
float u_price;//单价
string public_house;//出版社
static float total;//总价
static float aver_a;//所有书价平均值
static int a_n;//总书数
public:
xh_book();
//不全带默认值,避免定义不传参对象时不知道使用哪个普通构造函数
xh_book(string name, float price = 88.88, string house = "中山大学新华学院出版社"):b_name(name),u_price(price),public_house(house){}
~xh_book();//析构函数
xh_book(const xh_book&);//拷贝函数
static void cal_aver();
void out();//输出三个数据成员
void xiugai()//修改数据成员
{
cout << "依次输入修改后的书名、单价、出版社:";
cin >> this->b_name >> this->u_price >> this->public_house;
return;
}
void in()//每本书价格相加
{
total += u_price;
++a_n;//书总数加一
return;
}
};
float xh_book::total = 0;
int xh_book::a_n = 0;
void xh_book::out()
{
cout << "书名:" << b_name << endl
<< "单价:" << u_price << endl
<< "出版社:" << public_house << endl;
return;
}
void xh_book::cal_aver()
{
cout << "所有书本总价格:" << total << endl
<< "总书本数:" << a_n <<endl;
cout << "平均值:" << ((a_n == 0) ? 0 : (total / a_n)) << endl;//无书本时输出 0 ,有书本时输出平均值
}
xh_book::xh_book(const xh_book& copy_ed)
{
b_name = copy_ed.b_name;
u_price = copy_ed.u_price;
public_house = copy_ed.public_house;
}
xh_book::xh_book()
{
b_name = "清明节放假通知";
u_price = 0.5;
public_house = "中山大学教务处";
}
xh_book:: ~xh_book() { cout << "析构函数被调用……" << endl; }
int main()
{
xh_book b1("四级单词书", 78.9, "清华大学出版社");//创建一个对象
b1.out();//输出测试是否创建成功,私有数据只能通过公有成员函数间接访问
b1.cal_aver();//查看总价和平均值,预期输出为 0 ,因为没调用 in 函数改变静态数据成员
xh_book b_array[5] = { b1,b1,b1,b1,b1};
for (int i = 0; i < 5; ++i)
{
b_array[i].in();
b_array[i].out();
}
b1.cal_aver();//因为总价等是静态成员,预期输出不再为 0 ,而是后面创建的 5 个对象的平均值
b_array[0].cal_aver();
b_array[3].cal_aver();//因为静态数据成员相当于类内的全局变量,所以任何本类对象都可以访问到改变后的静态数据成员,并且一样
xh_book b2;//不传参,调用不带默认值的普通构造函数,不能给写 b2(),系统会认为是声明函数
b2.out();//检验
xh_book b3("高等数学");//只传书名,价格和出版社不变
b3.out();
b3.xiugai();//修改高等数学这本书
b3.out();
return 0;
}
五、总结
①静态数据成员一定要初始化且在类外
②定义了无形参构造函数就不要再定义全带默认值的构造函数
③复制构造函数形参加const保护被复制的对象
④静态成员函数不能访问操作非静态数据成员
⑤静态数据成员改变了,再使用任何对象访问都是改变后的数据
⑥类外定义成员函数要在数据类型和函数名中间加类名::