1.

bank.h

#include <string>
using namespace std; class BankAccount
{
private:
std::string m_name;//若是不用命名空间的话,就需要加std::
string m_id;
double m_money;
public:
BankAccount();
BankAccount(const string & name,const string & id,double money=0.0);
void show() const;
void add(double money);
void sub(double money);
};

bank.cpp

#include <iostream>
#include "bank.h" //构造函数
BankAccount::BankAccount(){
m_name = "";
m_id = "";
m_money = 0.0;
}
BankAccount::BankAccount(const string & name,const string & id,double money){
m_name = name;
m_id = id;
m_money = money;
} void BankAccount::show() const{
ios_base::fmtflags orig=cout.setf(ios_base::fixed,ios_base::floatfield);//设置cout对象的一个标记,命令cout使用定点表示法
streamsize prec=cout.precision();
cout<< "Name: " << m_name << " ID: " << m_id << " Money: " << m_money << endl; //因为bank.h中已经声明了命名空间,所以不需要加std::
}
void BankAccount::add(double money){
m_money += money;
}
void BankAccount::sub(double money){
m_money -= money;
}

main.cpp

#include "bank.h"

void main(){
BankAccount a("MR.Zhang","",8888888.88);
a.show();
a.add(88888.88);
a.show();
a.sub(88888.88);
a.show();
system("pause");
}


//person.h
#include <string> class Person {
private:
static const int LIMIT = ;
std::string lname;
char fname[LIMIT];
public:
Person() { lname = ""; fname[] = '\0'; } //无参数
Person(const std::string &ln, const char *fn = "Heyyou"); //两参数
void Show() const;
void FormalShow() const;
}; //person.cpp
#include <iostream>
#include "Person.h" Person::Person(const std::string & ln, const char *fn)
{
lname = ln;
strncpy_s(fname, fn ,); //fname的长度为25
}
void Person::Show() const
{
std::cout << fname << " " << lname << std::endl;
} void Person::FormalShow() const
{
std::cout << lname << ", " << fname << std::endl;
} //main.cpp
#include "person.h" void main(){
Person one;
Person two("Smythecraft");
Person three("Dimwiddy", "Sam");
one.Show();
one.FormalShow();
two.Show();
two.FormalShow();
three.Show();
three.FormalShow();
system("pause");
}

前两行的显示:one为空,没有输出,FormalShow有一个逗号


3.完成第9章的编程练习1,但要用正确的golf类声明替换那里的代码。用带合适参数的构造函数替换setgolf ( golf &, const char*, int), 以提供初始值。保留setgolf()的交互版本,但要用构造函数来实现它(例如,setgolf()的代码应该获得数据,将数据传递给构造函数来创建一个临时对象,并将其赋给调用对象,即*this)。

4.完成第9章的编程练习4,但将Sales结构及相关的函数转换为一个类及其方法。用构造函数替换setSales ( sales&, double [] , int)函数。用构造函数实现setSales(Sales&)方法的交互版本。将类保留在名称空间SALES中。

这两题参考http://blog.csdn.net/qq20004604/article/details/50540039  或者   http://blog.csdn.net/acm_yuuji/article/details/47374799


5.考虑下面的结构声明:
struct customer {

  char fullname[35];

  double payment;

};

编写一个程序,它从栈中添加和删除cunstomer结构(栈用Stack类声明表示)。每次customer结构被删除时,其payment的值都将被加入到总数中,并报告总数。注意:应该可以直接使用Stack类而不做修改;只需修改typedef声明,使Item的类型为customer,而不是unsigned long即可。

//stack.h
struct customer{
char fullname[];
double payment;
};
typedef customer Item; class Stack //类声明
{
private:
double total;
enum{MAX=};
Item items[MAX];
int top;
public:
Stack(); //默认构造函数
bool isempty() const;
bool isfull() const;
bool push(const Item & item);//压栈
bool pop(Item & item);//出栈
}; //stack.cpp
#include <iostream>
#include "stack.h" //构造函数
Stack::Stack(){
top=;
total=;
} bool Stack::isempty() const{
return top==;//top为0返回true,反之为false
}
bool Stack::isfull() const{
return top==MAX;
}
bool Stack::push(const Item &item){
if(top<MAX){
items[top++]=item;
return true;
}else
return false;
}
bool Stack::pop(Item &item){
if(top>){
item=items[--top];
total += item.payment;
std::cout << "总共已取出" << total << "元" << std::endl;
return true;
}else
return false;
} //main.cpp
#include<iostream>
#include<cctype>
#include "stack.h"
using namespace std; void main(){
cout.setf(ios_base::fixed);
cout.precision(); //设置输出保留两位小数
Stack st;//创建对象储物柜
customer one;
char ch;
cout<<"Enter A to save money, P to withdraw money, Q to quit.\n";
while (cin>>ch&&toupper(ch)!='Q')
{
while(cin.get()!='\n')//如果不是换行就继续
continue;
if (!isalpha(ch))//如果不是字母就继续
{
cout<<'\a';
continue;
}
switch (ch)
{
case 'A':
case 'a':
if(st.isfull())//该方法判断:如果满了(top等于MAX)返回true,没满返回false
cout<<"Stack already full\n";
else{
cout << "请输入存钱的人的名字:";
cin.getline(one.fullname,);
cout << "请输入要存多少钱:";
cin >> one.payment;
cin.sync(); //清除输入缓存,防止干扰
if (st.push(one))
cout << "存放成功!" << one.fullname << " 共计 " << one.payment << " 元钱已经被存进来啦!" << endl;
else
cout << "由于某种未知的原因,存放失败了。。。。" << endl;
}
break;
case 'P':
case 'p':
if(st.isempty())
cout<<"Stack already empty\n";
else{
st.pop(one);
}
break;
}
cout<<"Enter A to save money, P to withdraw money, Q to quit.\n";
}
system("pause");
}


//1.h
class Move
{
private:
double x;
double y;
public:
Move(double a = , double b = ); //set x,y to a,b
void showmove()const; //shows current x,y values
Move add(const Move & m) const; //这个函数将被调用对象m的x和y值与自己的x,y值相加,并得到2个新值,然后创建一个使用新的x、y值的move对象,并将增加后的x、y值赋给她,然后将这个新对象作为返回值
void reset(double a = , double b = ); //resets x,y to a,b
}; //1.cpp
#include <iostream>
#include "1.h" Move::Move(double a, double b){
x = a;
y = b;
} void Move::showmove()const{
std::cout << "x = " << x << ", y = " << y << std::endl;
} Move Move::add(const Move & m) const{
Move q(this->x + m.x, this->y + m.y);
return q;
} void Move::reset(double a , double b ){
x = a;
y = b;
} //main.cpp
#include<iostream>
#include "1.h" void main(){
Move m,n(1.5,2.5);
m.showmove();
m=m.add(n);
m.showmove();
m.reset();
m.showmove();
system("pause");
}


7.Betelgeusean plorg有这些特征。

数据:

①plorg的名称不超过19个字符;

②plorg有满意指数(CI),这是一个整数。

操作:

①新的plorg将有名称,其CI值为50;

②plorg的CI可以修改;

③plorg可以报告其名称和CI;

④plorg的默认名称为“Plorga”。

请编写一个Plorg类声明(包括数据成员和成员函数原型)来表示plorg,并编写成员函数的函数定义。然后编写一个小程序,以演示Plorg类的所有特性。

//1.h
class Plorg
{
private:
char m_name[];
int m_CI;
public:
Plorg(char * name = "Plorga", int CI = );
void show()const;
void setName(const char *name);
void setCI(const int CI);
}; //1.cpp
#include <iostream>
#include "1.h" Plorg::Plorg(char * name, int CI){
strncpy_s(m_name, name,);
m_CI = CI;
} void Plorg::setName(const char *name){
strncpy_s(m_name, name,);
}
void Plorg::setCI(const int CI){
m_CI = CI;
}
void Plorg::show()const{
std::cout << "name = " << m_name << ", CI = " << m_CI << std::endl;
} //main.cpp
#include<iostream>
#include "1.h" void main(){
Plorg p;
p.show();
p.setName("Jany");
p.setCI();
p.show();
system("pause");
}


//list.h
#include <stdlib.h> //包含NULL的定义
typedef int Item; class List
{
private:
static const int LIMIT = ;
Item items[LIMIT];
int top;
public:
List() { top = ; } //默认构造函数
bool push(const Item); //添加数据项
bool isempty()const; //确定是否为空
bool isfull()const; //是否为满
void visit(void(*pf)(Item &m)); //显示每个数据项,并执行某种操作,具体是哪种,根据指针指向的函数而定
}; //list.cpp
#include "List.h" bool List::push(const Item item)
{
if (isfull() == true)
return false;
items[top++] = item;
return true;
} bool List::isempty() const
{
return top == ? true : false;
} bool List::isfull() const
{
return top == LIMIT ? true : false;
} void List::visit(void(*pf)(Item &item))
{
for (int i = ; i < top; ++i)
(*pf)(items[i]);
} //main.cpp
#include<iostream>
#include "list.h" void Print(Item &item)
{
std::cout << item << std::endl;
}
void main(){
List l;
l.push();
l.push();
l.push();
l.push();
if(l.isempty())
std::cout << "isEmpty? " << "Empty" << std::endl;
else
std::cout << "isEmpty? " << "Not Empty" << std::endl;
if(l.isfull())
std::cout << "isFull? " << "Full" << std::endl;
else
std::cout << "isFull? " << "Not Full" << std::endl;
void(*pf)(Item &item);
pf = Print; //或者 void(*pf)(Item &item) = Print
l.visit(pf);
system("pause");
}

总结:

①在类中以函数指针作为参数的时候,纠结了很久,查了别人的答案才明白。

例如:void visit( void (*pf)(Item& m) );

这个的意思是,visit函数中,使用函数指针pf作为参数。

在调用visit函数时,哪个函数名作为参数放在里面,那么pf指针就指向哪个函数(前提是类型相同)。

因为指针作为参数,所以参数有点类似( char* pa)这样的意思,char*表示pa是char类型的指针,但不是说char*是参数,所以函数指针作为参数时,重点是pf,而不是外面那个修饰pf的。

可以使用typedef void (*PP)(Item &m);将PP作为这个的别名,于是可以改为void visit(PP pf);这样。

因为没把函数指针学透,纠结了很久,写完代码才想明白。

因为pf是函数指针,所以函数内部的pf(items[i])是将items[i]作为参数给pf指向的函数。例如当show函数作为参数给visit时,这里相当于show(items[i])。

版权声明:出处http://blog.csdn.net/qq20004604

[C++ Primer Plus] 第10章、对象和类(二)课后习题的更多相关文章

  1. C++ primer plus读书笔记——第10章 对象和类

    第10章 对象和类 1. 基本类型完成了三项工作: 决定数据对象需要的内存数量: 决定如何解释内存中的位: 决定可使用数据对象执行的操作或方法. 2. 不必在类声明中使用关键字private,因为这是 ...

  2. 《C++ Primer Plus》第10章 对象和类 学习笔记

    面向对象编程强调的是程序如何表示数据.使用 OOP 方法解决编程问题的第一步是根据它与程序之间的接口来描述数据,从而指定如何使用数据.然后,设计一个类来实现该接口.一般来说,私有数据成员存储信息,公有 ...

  3. 《C++ Primer Plus》10.2 抽象和类 学习笔记

    10.2.1 类型是什么基本类型完成了下面的三项工作:* 决定数据对象需要的内存数量:* 决定如何解释内存中的位(long和float在内存中占用的位数相同,但是将它们转换为数值的方法不同):* 决定 ...

  4. [C++ Primer Plus] 第7章、函数(二)课后习题

    一.复习题 6.为什么不对基本数据类型的函数参数使用const? 8.编写一个函数,将字符串中所有c1替换成c2,并返回替换次数. #include<iostream> using nam ...

  5. [C++ Primer Plus] 第10章、对象和类(一)程序清单——辨析三个const

    程序清单10.1+10.2+10.3 头文件stock.h #ifndef STOCK00_H_ //先测试x是否被宏定义过 #define STOCK00_H_ //如果没有宏定义,就宏定义x并编译 ...

  6. C Primer Plus 第10章 数组和指针 编程练习

    这章感觉好难啊,放个别人的总结. // 多维数组和指针 #include <stdio.h> int main(void) { int zippo[4][2] = {{2, 4}, {6, ...

  7. C++ Primer 5th 第10章 泛型算法

    练习10.1:头文件algorithm中定义了一个名为count的函数,它类似find,接受一对迭代器和一个值作为参数.count返回给定值在序列中出现的次数.编写程序,读取int序列存入vector ...

  8. C Primer Plus_第10章_数组和指针_编程练习

    1. /*rain.c 针对若干年的降水量数据,计算年降水总量.年降水平均量,以及月降水平均量*/ #include <stdio.h> #define MONTHS 12 #define ...

  9. 《C++ primer》--第10章

    习题10.21 解释map和set容器的差别,以及他们各自适用的情况. 解答: map容器和set容器的差别在于: map容器是键-值对的集合,而set容器只是键的集合: map类型适用于需要了解键与 ...

随机推荐

  1. VS2015中使用报表控件(ReportViewer)的方法

    没有报表,一般默认安装之后会出现这种情况,在安装的时候选择自定义安装,把Microsoft Office 开发人员工具.Microsoft SQL Server Data Tools勾选上,安装之后就 ...

  2. Django中的form组件

    Django中的form组件有两大作用 1.验证获取正确的结果或者错误信息 2.生成html代码 一.为什么需要form组件呢? 在写form表单,提交数据时,自己写验证的代码是一件非常困难的事情. ...

  3. RuntimeError: implement_array_function method already has a docstring

    根源:Numpy/Scipy/Pandas/Matplotlib/Scikit-learn 出现冲突 解决办法: pip uninstall scikit-learn pip uninstall ma ...

  4. Asp.net 使用线程池实例

    实际开发经常会使用线程,如果每次使用都是创建线程.启动线程,然后销毁线程,从性能上来讲,非常占用系统开销,当线程达到一定量的时候会影响程序的运行和处理效率. 使用线程池:好处:线程池是一种多线程处理形 ...

  5. springcloud第三步:发布服务消费者

    服务消费者 创建项目sercice-order Maven依赖 <parent> <groupId>org.springframework.boot</groupId&g ...

  6. 代码混淆工具——Virbox Protector Standalone

    VirboxProtector Standalone 加壳工具可对代码加密的技术有:代码混淆.代码虚拟化.代码加密. 代码混淆:利用花指令和代码非等价变形等技术,将程序的代码,转换成一种功能上等价,但 ...

  7. Oracle SQL Loader

    C:/Documents and Settings/WWJD>sqlldr SQL :: Copyright (c) , , Oracle. All rights reserved. 用法: S ...

  8. 《linux就该这么学》第十七节课:第18,19,23章,mariadb数据库、PXE无人值守安装系统和openldap目录服务。

    第23章 (借鉴请改动) openldap数据的特点:1.短小.2.读取次数较多 上述说明: openLDAP服务端配置:     1.yum install -y openldap openldap ...

  9. linux----------fedora 27 如何启用输入法

    1.安装完成以后是自带了输入法的,但是需要启用. 一定要放到第一个位置,然后注销或者重启.

  10. #WEB安全基础 : HTTP协议 | 0x15 HTTPS:给你点颜色看看

    "你好,我是HTTPS,我只是披了个外壳,我还是原来的HTTP." 这是HTTPS叫我转达给你的话. HTTPS本质上就是HTTP,只不过加了点调料.它比HTTP更安全,使用了加密 ...