第一题
对于下面类声明
class Cow
{
char name[20];
char* hobby;
double weight;
public:
Cow();
Cow(const char* nm, const char* ho, double wt);
Cow(const Cow& c);
~Cow();
Cow& operator=(const Cow& c);
void ShowCow()const;
};
给这个类提供实现,并编写一个使用所有成员函数的小程序
cow.h头文件
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#ifndef _COW_
#define _COW_
class Cow
{
char name[20];
char* hobby;
double weight;
public:
Cow()
{
name[0] = '\0';
hobby = nullptr;
weight = 0.0;
}
Cow(const char* nm, const char* ho, double wt)
{
strncpy(name, nm,20 - 1);
name[20 - 1] = '\0';
hobby = new char[strlen(ho) + 1];
weight = wt;
strcpy(hobby, ho);
}
Cow(const Cow& c)
{
strcpy(name, c.name);
hobby = new char[strlen(c.hobby) + 1];
weight = c.weight;
strcpy(hobby, c.hobby);
}
~Cow()
{
delete[]hobby;
}
Cow& operator=(const Cow& c)
{
if (this == &c)
return *this;
delete[]hobby; //可用于nullptr
strcpy(name, c.name);
if (c.hobby != nullptr)
{
hobby = new char[strlen(c.hobby) + 1];
strcpy(hobby, c.hobby);
}
else
hobby = nullptr;
weight = c.weight;
return*this;
}
void ShowCow()const
{
if (hobby == nullptr)
{
std::cout << "name:" << name << std::endl
<< "hobby: " << "nullptr" << std::endl
<< "weight: " << weight << std::endl;
return;
}
std::cout << "name:" << name << std::endl
<< "hobby: " << hobby << std::endl
<< "weight: " << weight << std::endl;
}
};
#endif
main.cpp
#define _CRT_SECURE_NO_WARNINGS //vs里添加这个宏不然编译器认为strcpy不安全 记住头文件里函数的定义为内联函数
#include"cow.h"
int main()
{
using std::cout;
using std::endl;
Cow c("lesson","hello",2.1);
Cow d;
cout << "c:\n";
c.ShowCow();
cout << "d:\n";
d.ShowCow();
d = c;
cout << "d:\n";
d.ShowCow();
cout << "e:\n";
Cow e;
e.ShowCow();
cout << "e:\n";
e = Cow("order","hello",2.1); //先调用复制函数 在调用赋值函数
e.ShowCow();
cout << "p:\n";
Cow* p = nullptr;
p = new Cow(e);
p->ShowCow();
delete p;
return 0;
}
运行结果
第二题
通过完成下面的工作来改进String类声明(即将String1.h升级为String2.h)
a.对+运算符进行重载,使之可将两个字符串合并成1个。
b.提供一个stringlow()成员函数,将字符串所有的字母字符转换为小写(别忘了cctype系列字符函数)。
c.提供String()成员函数,将字符串中所有字母转换成大写。
d.提供一个这样的成员函数,它接受一个char参数,返回该字符在字符串中出现的次数。
略:
String2.h头文件
#ifndef STRING1_H_
#define STRING1_H_
#include<iostream>
using std::ostream;
using std::istream;
class String
{
private:
char* str;
int len;
static int num_strings; //对象数
static const int CINLIM = 80; //CIN输入限制
public:
//构造函数和其他方法
String(const char* s); //构造 函数
String(); //默认构造函数
String(const String&); //复制构造函数
~String();
int length()const { return len; }
void stringlow();
void stringup();
int has(char);
String& operator=(const String&);
String& operator=(const char*);
String& operator+(const String&);
char& operator[](int i);
const char& operator[](int i)const;
friend bool operator<(const String& st, const String& st2);
friend bool operator>(const String& st, const String& st2);
friend bool operator==(const String& st, const String& st2);
friend ostream& operator<<(ostream& os, const String& st);
friend istream& operator>>(istream& is, String& st);
friend String operator+(const char* str, const String& st2);
//static function
static int How_Many();
};
#endif
String.cpp
#define _CRT_SECURE_NO_WARNINGS 21
#include"string2.h"
#include<cstring>
#include<cctype>
using std::cin;
using std::cout;
int String::num_strings = 0;
int String::How_Many()
{
return num_strings;
}
String::String(const char* s)
{
len = std::strlen(s);
str = new char[len + 1];
std::strcpy(str, s);
num_strings++;
}
String::String()
{
len = 4;
str = new char[1];
str[0] = '\0';
num_strings++;
}
String::String(const String& st)
{
num_strings++;
len = st.len;
str = new char[len + 1];
std::strcpy(str, st.str);
}
String::~String()
{
--num_strings;
delete[]str;
}
String& String::operator=(const String& st)
{
if (this == &st)
return *this;
delete[]str;
len = st.len;
str = new char[len + 1];
std::strcpy(str, st.str);
return *this;
}
String& String::operator=(const char* s)
{
delete[] str;
len = std::strlen(s);
str = new char[len + 1];
std::strcpy(str, s);
return*this;
}
String& String::operator+(const String& st)
{
len = strlen(str) + strlen(st.str);
char* p = new char[len + 1];
strcpy(p, str);
strcat(p, st.str);
delete[] str;
str = p;
return *this;
}
char& String::operator[](int i)
{
return str[i];
}
const char& String::operator[](int i)const
{
return str[i];
}
bool operator<(const String& st1, const String& st2)
{
return (std::strcmp(st1.str, st2.str) < 0);
}
bool operator>(const String& st1, const String& st2)
{
return st2.str < st1.str;
}
bool operator==(const String& st1, const String& st2)
{
return (std::strcmp(st1.str, st2.str) == 0);
}
ostream& operator<<(ostream& os, const String& st)
{
os << st.str;
return os;
}
istream& operator>>(istream& is, String& st)
{
char temp[String::CINLIM];
is.get(temp, String::CINLIM);
if (is)
st = temp;
while (is && is.get() != '\n')
continue;
return is;
}
String operator+(const char* str, const String& st2)
{
String temp;
temp.len = strlen(str) + strlen(st2.str);
temp.str = new char[temp.len + 1];
strcpy(temp.str, str);
strcat(temp.str, st2.str);
return temp;
}
void String::stringlow()
{
for (int i = 0; i < len + 1; i++)
{
str[i] = tolower(str[i]);
}
}
void String::stringup()
{
for (int i = 0; i < len + 1; i++)
{
str[i] = toupper(str[i]);
}
}
int String::has(char a)
{
int count = 0;
for (int i = 0; i < len + 1; i++)
{
if (a == str[i])
count++;
}
return count;
}
pel2_2.cpp
#include<iostream>
using namespace std;
#include"string2.h"
int main()
{
String s1(" and I am a C++ student.");
String s2 = "please enter your name: ";
String s3;
cout << s2;
cin >> s3;
s2 = "My name is " + s3;
cout << s2 << ".\n";
s2 = s2 + s1;
s2.stringup();
cout << "The string\n" << s2 << "\ncontains " << s2.has('A')
<< " 'A' characters in it.\n";
s1 = "red";
String rgb[3] = { String(s1),String("green"),String("blue") };
cout << "Enter the name of a primary color for mixing light: ";
String ans;
bool success = false;
while (cin >> ans)
{
ans.stringlow();
for (int i = 0; i < 3; i++)
{
if (ans == rgb[i])
{
cout << "That's right!\n";
success = true;
break;
}
}
if (success)
break;
else
cout << "Try again!\n";
}
cout << "Bye\n";
return 0;
}
运行结果:
第3题
新编写程序清单10.7和程序清单10.8描述的Stock类,使之使用动态内存分配,而不是string类对象来存储股票名称。另外,使用重载的operator<<()定义代替show()成员函数。再使用程序清单10.9测试新的定义程序。
stock.h
#ifndef STOCK20_H_
#define STOCK20_H_
#include<string>
#include<iostream>
using std::ostream;
using std::istream;
class Stock
{
private:
char* company;
int shares;
double share_val;
double total_val;
void set_tot() { total_val = shares * share_val; }
public:
Stock();//default constructor
Stock(const char* str, long n = 0, double pr = 0.0);
~Stock();//do-nothing destructor
void buy(long num, double price);
void sell(long num, double price);
void update(double price);
const Stock& topval(const Stock& s)const;
friend ostream& operator<<(ostream& fout, const Stock& stocks);
};
#endif
stock.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"stock.h"
Stock::Stock()
{
company = nullptr;
shares = 0;
share_val = 0.0;
total_val = 0.0;
}
Stock::Stock(const char* str, long n, double pr)
{
company = new char[strlen(str) + 1];
strcpy(company, str);
if (n < 0)
{
std::cout << "Number of shares can't be negative; "
<< company << " shares set to 0.\n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
Stock::~Stock()
{
delete[]company;
}
void Stock::buy(long num, double price)
{
if (num < 0)
std::cout << "Number of shares purchased can't be negative. "
<< "Transaction is aborted.\n";
else
{
shares += num;
share_val = price;
set_tot();
}
}
void Stock::sell(long num, double price)
{
using std::cout;
if (num < 0)
{
cout << "Number of shares sold can't be negative. "
<< "Transaction is aborted.\n";
}
else if (num > shares)
{
cout << "You can't sell more than you have! "
<< "Transaction is aborted.\n";
}
else
{
shares -= num;
share_val = price;
set_tot();
}
}
void Stock::update(double price)
{
share_val = price;
set_tot();
}
const Stock& Stock::topval(const Stock& s)const
{
if (s.total_val > total_val)
return s;
else
return *this;
}
ostream& operator<<(ostream& fout, const Stock& stocks)
{
fout << "Company: " << stocks.company
<< "shares: " << stocks.shares << '\n';
fout << " share Price: $" << stocks.share_val;
fout << " Total Worth: $" << stocks.total_val << '\n';
return fout;
}
stock_main.cpp
#include<iostream>
#include"stock.h"
const int STKS = 4;
int main()
{
Stock stocks[STKS] =
{
Stock("NanoSmart",12,20.0),
Stock("Boffo objects",200,2.0),
Stock("Monolithic oblisks",130,3.25),
Stock("Fleep Enterprises",60,6.5)
};
std::cout << "Stock holdings:\n";
int st;
for (st = 0; st < STKS; st++)
std::cout << stocks[st];
const Stock* top = &stocks[0];
for (st = 1; st < STKS; st++)
top = &top->topval(stocks[st]);
std::cout << "\nMost valuable holding:\n";
std::cout << *top;
return 0;
}
运行结果
第4题
请看下面程序清单10.10定义的Stack类的变量
略
正如私有成员表明的,这个类使用动态分配的数组来保存栈项。请重新编写方法,以适应这种新的表示法,并编写一个程序来演示所有的方法,包括复制构造函数和赋值运算符。
stack.h
#ifndef STACK_
#define _STACK_
typedef unsigned long Item;
class Stack
{
private:
enum{MAX = 10};
Item* pitems;
int size;
int top;
public:
Stack(int n = MAX);
Stack(const Stack& st);
~Stack() { delete[]pitems; }
bool isempty()const;
bool isfull()const;
bool push(const Item& item);
bool pop(Item& item);
Stack& operator=(const Stack& st);
};
#endif
stack.cpp
#include"stack.h"
#include<iostream>
Stack::Stack(int n)
{
pitems = new Item[n];
size = top = 0;
}
Stack::Stack(const Stack& st)
{
pitems = new Item[MAX];
for (int i = 0; i < st.size; i++)
{
pitems[i] = st.pitems[i];
}
size = st.size;
top = st.top;
}
bool Stack::isempty()const
{
return size == 0;
}
bool Stack::isfull()const
{
return size == MAX;
}
bool Stack::push(const Item& item)
{
if (isfull())
{
std::cout << "full\n";
return false;
}
pitems[top++] = item;
size += 1;
return true;
}
bool Stack::pop(Item& item)
{
if (isempty())
{
std::cout << "empty\n";
return false;
}
item = pitems[--top];
size -= 1;
return true;
}
Stack& Stack::operator=(const Stack& st)
{
for (int i = 0; i < st.size; i++)
{
pitems[i] = st.pitems[i];
}
size = st.size;
top = st.top;
return *this;
}
stack_main.cpp
#include<iostream>
#include"stack.h"
using std::cout;
using std::endl;
using std::cin;
int main()
{
Stack stacks;
Item number = 0;
cout << "Enter a number:\n";
while (cin >> number)
{
if (stacks.push(number))
cout << "Successful onboarding\n";
}
Stack stack1 = stacks; //复制构造函数
if (stacks.pop(number))
cout << "stacks: " << number << endl;
if (stack1.pop(number))
cout << "stacks1: " << number << endl;
Stack stack2;
stack2 = stack1; //赋值
stack2.pop(number);
cout << "stacks2: " << number << endl; //这里的number的值是上一个值
return 0;
}
运行结果
第5题
略
这里的意思是要你把书里的程序自己测试 我的客户数是19和18
第6题
Heather银行想知道,如果再开启一台ATM,情况将如何。请对模拟就行修改,以包含两个队列。假设当第一台ATM的排队人数少于第二台ATM时,客户将排在第一队,否则排在第二队。然后再找出要使平均等候时间为1分钟,每小时到达的客户数应为多少(注意,这是一个非线性问题,即将ATM数量加倍,并不能保证每小时处理客户数量也翻倍,并确保客户等候时间少于1分钟)?
queue.h
#ifndef QUEUE_H_
#define QUEUE_H_
//此队列将包含客户项
class Customer
{
private:
long arrive; //客户到达的时间
int processtime; //客户处理的时间
public:
Customer() { arrive = processtime = 0; }
void set(long when);
long when()const { return arrive; }
int ptime()const { return processtime; }
};
typedef Customer Item;
class Queue
{
private:
//类作用域定义 节点是此类的本地嵌套结构定义
struct Node { Item item; struct Node* next; };
enum { Q_SIZE = 10 };
//私有类成员
Node* front; //指向队列前面的指针
Node* rear; //指向队列后面的指针
int items; //队列中的当前项目数
const int qsize; //队列中的最大项目数
//抢占式定义以防止公开复制
Queue(const Queue& q) : qsize(0) {}
Queue& operator=(const Queue& q) { return *this; }
public:
Queue(int qs = Q_SIZE);
~Queue();
bool isempty()const;
bool isfull()const;
int queuecount()const;
bool enqueue(const Item& item); //将项目添加到末尾
bool dequeue(Item& item); //从前面删除项目
};
#endif
queue.cpp
#include"queue.h"
#include<cstdlib>
//队列方法
Queue::Queue(int qs) : qsize(qs)
{
front = rear = nullptr;
items = 0;
}
Queue::~Queue()
{
Node* temp;
while (front != nullptr)
{
temp = front;
front = front->next;
delete temp;
}
}
bool Queue::isempty()const
{
return items == 0;
}
bool Queue::isfull()const
{
return items == qsize;
}
int Queue::queuecount()const
{
return items;
}
//将项目添加到队列
bool Queue::enqueue(const Item& item)
{
if (isfull())
return false;
Node* add = new Node; //创建节点
add->item = item;
add->next = nullptr;
items++;
if (front == nullptr)
front = add;
else
rear->next = add;
rear = add;
return true;
}
bool Queue::dequeue(Item& item)
{
if (front == nullptr)
return false;
item = front->item;
items--;
Node* temp = front;
front = front->next;
delete temp;
if (items == 0)
rear = nullptr;
return true;
}
void Customer::set(long when)
{
processtime = std::rand() % 3 + 1; //处理客户的时候 0-3之间的值
arrive = when; //客户到达的时间
}
queue_main.cpp
#include<iostream>
#include<cstdlib>
#include<ctime>
#include"queue.h"
const int MIN_PER_HR = 60;
bool newcustomer(double x);
int main()
{
using std::cin;
using std::cout;
using std::endl;
using std::ios_base;
//setting things up
std::srand(std::time(0));
cout << "Case Study: Bank of Heather Automatic Teller\n";
cout << "Enter maximum size of queue: "; //输入队列的最大大小
int qs;
cin >> qs;
Queue line1(qs); //第一队
Queue line2(qs); //第二队
cout << "Enter the number of simulation hours: "; //输入模拟小时数
int hours;
cin >> hours;
//模拟将每分钟运行 1 个周期
long cyclelimit = MIN_PER_HR * hours;
cout << "Enter the average number of customers per hour: "; //输入每小时的平均客户数
double perhour; //每小时平均 # 到达次数
cin >> perhour;
double min_per_cust; //到达之间的平均时间
min_per_cust = MIN_PER_HR / perhour; //几分钟到达一个人
Item temp; //新客户数据
//第一队
long turnaways1 = 0; //被满队列拒之门外
long customers1 = 0; //加入队列
long served = 0; //在模拟期间服务
long sum_line1 = 0; //累积线长度
int wait_time1 = 0;
long line_wait1 = 0; //累计排队时间
//第二队
long wait_time2 = 0;
for (int cycle = 0; cycle < cyclelimit; cycle++)
{
if (newcustomer(min_per_cust))
{
if (line1.queuecount() < line2.queuecount())
{
if (line1.isfull()) //检查是否已满
turnaways1++;
else
{
customers1++;
temp.set(cycle); //周期 = 到达时间
line1.enqueue(temp);
}
}
else
{
if (line2.isfull())
turnaways1++;
else
{
customers1++;
temp.set(cycle);
line2.enqueue(temp);
}
}
}
if (wait_time1 <= 0 && !line1.isempty())
{
line1.dequeue(temp); //参加下一位客户
wait_time1 = temp.ptime(); //wait_time分钟 得到客户处理的时间
line_wait1 += cycle - temp.when(); //累计排队时间
served++; //模拟期间服务的次数
}
if (wait_time2 <= 0 && !line2.isempty())
{
line2.dequeue(temp);
wait_time2 = temp.ptime();
line_wait1 += cycle - temp.when();
served++;
}
if (wait_time1 > 0)
wait_time1--; //wait_time==0表示客户已经处理完成
if (wait_time2 > 0)
wait_time2--;
sum_line1 += line1.queuecount();
sum_line1 += line2.queuecount();
}
if (customers1 > 0)
{
cout << "customers accepted1: " << customers1 << endl;
cout << " customers served1: " << served << endl;
cout << " turnaways1: " << turnaways1 << endl;
cout << "average queue size1: ";
cout.precision(2);
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << (double)sum_line1 / cyclelimit << endl;
cout << " average wait time1: "
<< (double)line_wait1 / served << " minutes\n";
}
else
cout << "No customers!\n";
cout << "Done!\n";
return 0;
}
//x = 客户之间的平均时间(以分钟为单位),如果客户显示分钟,则返回值为 true
bool newcustomer(double x)
{
return (std::rand() * x / RAND_MAX < 1); //0到x之间 每隔x次,这个值就会小于1 理解:小于1的话就为到来一个人
}
运行结果