习题选自:C++ Primer Plus(第六版)
内容仅供参考,如有错误,欢迎指正 !

  • c++使用new和delete运算符来动态控制内存。
  • 对于静态成员,要在类声明之外使用单独语句进行初始化,因为静态类成员函数是单独存储的,而不是对象的组成部分,而且初始化是在方法文件中,而不是在头文件中,这是因为类声明位于头文件中,程序可能将头文件包括在其他几个文件中,如果在头文件中初始化,将出现多个初始化语句副本,从而引发错误。但如果静态成员是整形或枚举型const,则可以在类声明中初始化。
  • 私有静态变量有且仅在初始化时,才可以在外部访问。
  • 复制构造函数用于将一个对象复制到新创建的对象中,它用于初始化过程中(包括按值传递参数)。

复习题

1. 假设String 类有如下私有成员:
class String
{private:char * str;  //points to string allocated by newint len;    //holds length of string//...
};
a. 下述默认构造函数有什么问题?
String ::String() {}
b. 下述构造函数有什么问题?
String:: String (const char* s)
{str = s:len = strlen(s);
}
c. 下述构造西数有什么问题?
String: :String (const char* s)
{strcpy(str, s);len = strlen(s);
}

a. 语法是正确的,但该构造函数没有初始化str指针。该构造函数应该使用new[]来初始化它,或者将其设置为NULL。

b. 该构造函数没有创建新的字符串,只是复制了原有字符串的地址,它应当使用new[]和strcpy()。

c. 它虽然复制了字符串,但没有给他分配存储空间,应使用new char[len+1]来分配适当数量的内存。

2. 如果您定义了一个类,其指针成员是使用 new 初始化的,请指出可能出现的3个问题以及如何纠正这些问题。

可能出现的:

  • 问题一:当对象过期的时候,对象的成员指针指向的数据仍保留在内存中,造成内存泄漏。

    在析构函数中删除构造函数中new分配的内存,来解决该问题。

  • 问题二:如果使用对象初1始化为另一个对象2时,采用默认初始化的方式,则在对象1过期后,在对象2过期过程中,其析构函数会对同一块内存释放两次,造成错误。

    定义一个复制构造函数,使初始化复制指针指向的数据,而不是复制指针指向的地址。

  • 问题三:将一个对象赋给另一个对象也将导致两个指针指向同一个数据。

    重载赋值运算符,使之复制数据,而不是指针。

3. 如果没有显式提供类方法,编译器将自动生成哪些类方法?请描述这些隐式生成的函数的行为。

如果没有显示提供方法,c++将自动生成以下成员函数:

  • 构造函数:默认构造函数不完成任何工作,但使得能够声明数组和未初始化对象。
  • 复制构造函数:默认赋值构造函数使用成员赋值。
  • 赋值运算符:默认赋值运算法使用成员赋值。
  • 析构函数:默认析构函数不完成任何工作。
  • 地址运算符:隐式地址运算符返回调用对象的地址(即this指针的值)。
4. 找出并改正下述类声明中的错误:
class nifty
{// datachar personality[];int talents;// methodsnifty();nifty(char * s);ostream & operator<<(ostream & os, nifty & n);
}nifty:nifty()
{personality = NULL;talents = 0;
}nifty:nifty(char * s)
{personality = new char [strlen(s)];personality = s;talents = 0;
}ostream & nifty:operator<<(ostream & os, nifty & n)
{os << n;
}

应将personality成员声明为字符数组或car指针,或者将其声明为String对象。该声明没有将方法设置为公有的。修改后:

#include <iostream>
#include <cstring>
using namespace std;
class nifty
{private: // optionalchar personality[40]; // provide array sizeint talents;public: // needed// methodsnifty();nifty(const char * s);friend ostream & operator<<(ostream & os, const nifty & n);
}; // note closing semicolon
nifty::nifty()
{personality[0] = '\0';talents = 0;
}
nifty::nifty(const char * s)
{strcpy(personality, s);talents = 0;
}
ostream & operator<<(ostream & os, const nifty & n)
{os << n.personality << '\n';os << n.talent << '\n';return os;
}
5. 对于下面的类声明:
class Golfer
{private:char * fullname; // points to string containing golfer's nameint games; // holds number of golf games playedint * scores; // points to first element of array of golf scorespublic:Golfer();Golfer(const char * name, int g= 0);// creates empty dynamic array of g elements if g > 0Golfer(const Golfer & g);~Golfer();
};
a. 下列各条语句将调用哪些类方法?
Golfer nancy;                     // #1
Golfer lulu(“Little Lulu”);       // #2
Golfer roy(“Roy Hobbs”, 12);      // #3
Golfer * par = new Golfer;        // #4
Golfer next = lulu;               // #5
Golfer hazzard = “Weed Thwacker”; // #6
*par = nancy;                     // #7
nancy = “Nancy Putter”;           // #8
b. 很明显,类需要有另外几个方法才能更有用,但是类需要哪些方法才能防止数据被损坏呢?

a.

Golfer nancy;                     // 默认构造函数
Golfer lulu("Little Lulu");       // Golfer(const char * name, int g)
Golfer roy("Roy Hobbs", 12);      // Golfer(const char * name, int g)
Golfer* par = new Golfer;         // 默认构造函数
Golfer next = lulu;               // Golfer(const Golfer &g)
Golfer hazard = "Weed Thwacker";  // Golfer(const char * name, int g)
*par = nancy;                     // 默认赋值运算符
nancy = "Nancy Putter";           // 先调用Golfer(const char * name, int g), 再默认赋值运算符

b. 有以下两个方法:

  1. 防止拷贝,将赋值运算符(面向对象拷贝给对象的)/复制构造函数,放在私有部分;
  2. 类应定义一个复制数据(而不是地址)的赋值运算符。

编程练习

1. 对于下面的类声明:
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; // display all cow data
};
给这个类提供实现,并编写一个使用所有成员函数的小程序。

cow.h:

#ifndef COW_H_
#define COW_H_class Cow {private:char name[20];char * hobby;double weight;public:Cow(); Cow(const char * nm, const char * ho, double wt);Cow(const Cow & c);~Cow() { delete [] hobby; }Cow & operator=(const Cow & c);void show() const;
};#endif

cow.cpp:

#include "cow.h"#include <cstring>
#include <iostream>Cow::Cow() {name[0] = '\0';hobby = nullptr;weight = 0.0;
}Cow::Cow(const char* nm, const char* ho, double wt) {std::strncpy(name, nm, 20);int len = std::strlen(ho) + 1;hobby = new char[len];std::strcpy(hobby, ho);weight = wt;
}Cow::Cow(const Cow& c) {std::strncpy(name, c.name, 20);int len;len = std::strlen(c.hobby);hobby = new char[len];std::strcpy(hobby, c.hobby);weight = c.weight;
}Cow& Cow::operator=(const Cow& c) {if (this == &c) return *this;  // object assigned to itselfstd::strncpy(name, c.name, 20);delete[] hobby;int len;len = std::strlen(c.hobby);hobby = new char[len];std::strcpy(hobby, c.hobby);weight = c.weight;return *this;
}void Cow::show() const {std::cout << "name: " << name << std::endl;std::cout << "hobby: " << hobby << std::endl;std::cout << "weight: " << weight << std::endl;
}

main.cpp:

#include <iostream>
#include "cow.h"int main() {Cow c1("xiao", "eating", 100);c1.show();Cow c2 = c1;c2.show();Cow c3;c3 = c2;c3.show();return 0;
}
2. 通过下面的工作来改进String类声明(即将String1.h升级为String2.h)。
a. 对+运算符进行重载,使之可将两个字符串合并成一个。
b. 提供一个Stringlow()成员函数,将字符串中所有的字母字符转换为小写(别忘了cctype系列字符函数)。
c. 提供String()成员函数,将字符串中所有字母字符转换成大写。
d. 提供一个这样的成员函数,它接受一个char参数,返回该字符在字符串中出现的次数。
使用下面的程序来测试您的工作:
// pe12_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; // overloaded << operatorcin >> s3; // overloaded >> operators2 = "My name is " + s3; // overloaded =, + operatorscout << s2 << ".\n";s2 = s2 + s1;s2.stringup(); // converts string to uppercasecout << "The string\n" << s2 << "\ncontains " << s2.has('A')<< " 'A' characters in it.\n";s1 = "red"; // String(const char *),// then String & operator=(const String&)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(); // converts string to lowercasefor (int i = 0; i < 3; i++){if (ans == rgb[i]) // overloaded == operator{cout << "That's right!\n";success = true;break;}}if (success)break;elsecout << "Try again!\n";}cout << "Bye\n";return 0;
}
输出应与下面相似:
Please enter your name: Fretta Farbo
My name is Fretta Farbo.
The string
MY NAME IS FRETTA FARBO AND I AM A C++ STUDENT.
contains 6 'A' characters in it.
Enter the name of a primary color for mixing light: yellow
Try again!
BLUE
That's right!
Bye

string2.h:

#ifndef STRING2_H_
#define STRING2_H_#include <iostream>
using std::istream;
using std::ostream;class String {private:
char *str;
int len;
static int num_strings;
static const int CINLIM = 80;public:
String(const char *s);
String();
String(const String &s);
~String();
int length() const { return len; }
void stringlow();
void stringup();
int has(char x);String &operator=(const String &s);
String &operator=(const char *s);
char &operator[](int i);
const char &operator[](int i) const;String operator+(const String &s) const;
String operator+(const char *s) const;friend bool operator<(const String &s1, const String &s2);
friend bool operator>(const String &s1, const String &s2);
friend bool operator==(const String &s1, const String &s2);
friend ostream &operator<<(ostream &os, const String &st);
friend istream &operator>>(istream &is, String &st);
friend String operator+(const char *, const String &);static int HowMany();
};#endif  // STRING2_H_

string.cpp:

#include "string2.h"// #include <cctype>
#include <cstring>// initialize static members
int String::num_strings = 0;int String::HowMany() { 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 = 1;
str = new char[1];
str[0] = '\0';
num_strings++;
}String::String(const String &s) {len = s.len;
str = new char[len + 1];
std::strcpy(str, s.str);
num_strings++;
}String::~String() {--num_strings;
delete[] str;
}void String::stringlow() {for (int i = 0; i < len; ++i) {if (std::isupper(str[1])) str[i] = std::tolower(str[i]);
}
}
void String::stringup() {for (int i = 0; i < len; ++i)if (std::islower(str[i])) str[i] = std::toupper(str[i]);
}int String::has(char x) {int count = 0;
for (int i = 0; i < len; ++i) {if (str[i] == x) count++;
}
return count;
}String &String::operator=(const String &s) {if (this == &s) return *this;
delete[] str;
len = s.len;
str = new char[len + 1];
std::strcpy(str, s.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;
}char &String::operator[](int i) { return str[i]; }const char &String::operator[](int i) const { return str[i]; }String String::operator+(const String &s) const {int total_len = len + s.len;
char *tmp = new char[total_len + 1];
std::strcpy(tmp, str);
std::strcat(tmp, s.str);
String str_new = tmp;
delete[] tmp;
return str_new;
}String String::operator+(const char *s) const {String tmp = s;
String sum = *this + tmp;
return sum;
}bool operator<(const String &s1, const String &s2) {return (std::strcmp(s1.str, s2.str) < 0);
}
bool operator>(const String &s1, const String &s2) {return (std::strcmp(s1.str, s2.str) > 0);
}
bool operator==(const String &s1, const String &s2) {//比较相等的时候不考虑大小写,使用strcasecmp(linux)/stricmp(windows)
return (strcasecmp(s1.str, s2.str) == 0);
}
ostream &operator<<(ostream &os, const String &st) {os << st.str;
return os;
}
istream &operator>>(istream &is, String &st) {char tmp[String::CINLIM];
is.get(tmp, String::CINLIM);
if (is) st = tmp;
while (is && is.get() != '\n') continue;
return is;
}
String operator+(const char *s1, const String &s2) { return String(s1) + s2; }
3. 新编写程序清单10.7和程序清单10.8描述的Stock类,使之使用动态分配的内存,而不是string类对象来存储股票名称。另外,使用重

载的operator<<()定义代替show()成员函数。再使用程序清单10.9测试新的定义程序。

stock20.h:

// stock20.h -- augmented version
#ifndef STOCK20_H_
#define STOCK20_H_
#include <iostream>class Stock {private:char* company;int shares;double share_val;double total_val;void set_tot() { total_val = shares * share_val; }public:Stock();  // default constructorStock(const char* co, long n = 0, double pr = 0.0);~Stock();  // do-nothing destructorvoid buy(long num, double price);void sell(long num, double price);void update(double price);friend std::ostream& operator<<(std::ostream& os, const Stock& st);const Stock& topval(const Stock& s) const;
};
#endif

stock.cpp:

// stock20.h -- augmented version
#ifndef STOCK20_H_
#define STOCK20_H_
#include <iostream>class Stock {private:char* company;int shares;double share_val;double total_val;void set_tot() { total_val = shares * share_val; }public:Stock();  // default constructorStock(const char* co, long n = 0, double pr = 0.0);~Stock();  // do-nothing destructorvoid buy(long num, double price);void sell(long num, double price);void update(double price);friend std::ostream& operator<<(std::ostream& os, const Stock& st);const Stock& topval(const Stock& s) const;
};
#endif

usestock20.cpp:

// stock20.cpp -- augmented version
#include "stock20.h"#include <cstring>
// constructors
Stock::Stock()  // default constructor
{company = new char[std::strlen("no name") + 1];std::strcpy(company, "no name");shares = 0;share_val = 0.0;total_val = 0.0;
}
Stock::Stock(const char* co, long n, double pr) {company = new char[std::strlen(co) + 1];std::strcpy(company, co);if (n < 0) {std::cout << "Number of shares can’t be negative; " << company<< " shares set to 0.\n";shares = 0;} elseshares = n;share_val = pr;set_tot();
}
// class destructor
Stock::~Stock()  // quiet class destructor
{delete[] company;
}
// other methods
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();
}std::ostream& operator<<(std::ostream& os, const Stock& st) {using std::ios_base;// set format to #.###ios_base::fmtflags orig = os.setf(ios_base::fixed, ios_base::floatfield);std::streamsize prec = os.precision(3);os << "Company: " << st.company << " Shares: " << st.shares << '\n';os << " Share Price: $" << st.share_val;// set format to #.##os.precision(2);os << " Total Worth: $" << st.total_val << '\n';// restore original formatos.setf(orig, ios_base::floatfield);os.precision(prec);return os;
}const Stock& Stock::topval(const Stock& s) const {if (s.total_val > total_val)return s;elsereturn *this;
}
4.请看下面程序清单10.10定义的Stack类的变量:
// stack.h -- class declaration for the stack ADT
typedef unsigned long Item;
class Stack
{private:enum {MAX = 10}; // constant specific to classItem * pitems; // holds stack itemsint size; // number of elements in stackint top; // index for top stack itempublic:Stack(int n = MAX); // creates stack with n elementsStack(const Stack & st);~Stack();bool isempty() const;bool isfull() const;// push() returns false if stack already is full, true otherwisebool push(const Item & item); // add item to stack// pop() returns false if stack already is empty, true otherwisebool pop(Item & item); // pop top into itemStack & operator=(const Stack & st);
};
正如私有成员表明的,这个类使用动态分配的数组来保存栈项。请重新编写方法,以适应这种新的表示法,并编写一个程序来演示所有的方法,包括复制构造函数和赋值运算符。

stack.h:

// stack.h -- class declaration for the stack ADT
#ifndef STACK_H_
#define STACK_H_
#include <iostream>typedef unsigned long Item;
class Stack {private:enum { MAX = 10 };  // constant specific to classItem* pitems;       // holds stack itemsint size;           // number of elements in stackint top;            // index for top stack itempublic:Stack(int n = MAX);  // creates stack with n elementsStack(const Stack& st);~Stack();bool isempty() const;bool isfull() const;// push() returns false if stack already is full, true otherwisebool push(const Item& item);  // add item to stack// pop() returns false if stack already is empty, true otherwisebool pop(Item& item);  // pop top into itemStack& operator=(const Stack& st);friend std::ostream& operator<<(std::ostream& os, const Stack& st);
};#endif  // STACK_H_

stack.cpp:

// stack.cpp -- Stack member functions
#include "stack.h"
Stack::Stack(int n)  // create an empty stack
{size = MAX;top = 0;pitems = new Item[size];for (int i = 0; i < size; ++i) pitems[i] = 0;
}Stack::Stack(const Stack& st) {delete[] pitems;size = st.size;top = st.top;pitems = new Item[size];for (int i = 0; i < size; ++i) pitems[i] = st.pitems[i];
}Stack::~Stack() { delete[] pitems; }bool Stack::isempty() const { return top == 0; }
bool Stack::isfull() const { return top == MAX; }bool Stack::push(const Item& item) {if (top < MAX) {pitems[top++] = item;return true;} elsereturn false;
}bool Stack::pop(Item& item) {if (top > 0) {item = pitems[--top];return true;} elsereturn false;
}Stack& Stack::operator=(const Stack& st) {if (this == &st) return *this;delete[] pitems;size = st.size;top = st.top;pitems = new Item[size];for (int i = 0; i < size; ++i) pitems[i] = st.pitems[i];return *this;
}std::ostream& operator<<(std::ostream& os, const Stack& st) {for (int i = 0; i < st.top; i++) {os << st.pitems[i] << std::endl;}return os;
}

main.cpp:

// stacker.cpp -- testing the Stack class
#include <cctype>  // or ctype.h
#include <iostream>#include "stack.h"
int main() {using namespace std;Stack st;  // create an empty stackchar ch;unsigned long po;cout << "Please enter A to add a purchase order,\n"<< "P to process a PO, or 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':cout << "Enter a PO number to add: ";cin >> po;if (st.isfull())cout << "stack already full\n";elsest.push(po);break;case 'P':case 'p':if (st.isempty())cout << "stack already empty\n";else {st.pop(po);cout << "PO #" << po << " popped\n";}break;}cout << "Please enter A to add a purchase order,\n"<< "P to process a PO, or Q to quit.\n";}Stack st2;st2 = st;cout << "stack2 = stack is:\n" << st2;cout << "Bye\n";return 0;
}
5. Heather银行进行的研究表明,ATM客户不希望排队时间不超过1分钟。使用程序清单12.10中的模拟,找出要使平均等候时间为1分钟,每小时到达的客户数应为多少(试验时间不短于100小时)?

根据实际情况可知,每小时到达的客户数目越多,则平均等候时间越长,若要求平均等候时间为1分钟(即平均等候时间不超过1分钟时的临界情况)对应的每小时到达客户数,则我们可以让程序从每小时客户数从1开始计算(不小于100小时)其对应的平均排队时间,直到平均等待时间刚好超过1分钟的时候停止,此时对应的客户数(或者对应客户数-1)即为答案。

queue.h(未修改):

// queue.h -- interface for a queue
#ifndef QUEUE_H_
#define QUEUE_H_
// This queue will contain Customer items
class Customer {private:long arrive;      // arrival time for customerint processtime;  // processing time for customerpublic:Customer() { arrive = processtime = 0; }void set(long when);long when() const { return arrive; }int ptime() const { return processtime; }
};
typedef Customer Item;class Queue {private:// class scope definitions// Node is a nested structure definition local to this classstruct Node {Item item;struct Node* next;};enum { Q_SIZE = 10 };// private class membersNode* front;      // pointer to front of QueueNode* rear;       // pointer to rear of Queueint items;        // current number of items in Queueconst int qsize;  // maximum number of items in Queue// preemptive definitions to prevent public copyingQueue(const Queue& q) : qsize(0) {}Queue& operator=(const Queue& q) { return *this; }public:Queue(int qs = Q_SIZE);  // create queue with a qs limit~Queue();bool isempty() const;bool isfull() const;int queuecount() const;bool enqueue(const Item& item);  // add item to endbool dequeue(Item& item);        // remove item from front
};
#endif

queue.cpp(未修改):

// queue.cpp -- Queue and Customer methods
#include "queue.h"#include <cstdlib>  // (or stdlib.h) for rand()
// Queue methods
Queue::Queue(int qs) : qsize(qs) {front = rear = NULL;  // or nullptritems = 0;
}
Queue::~Queue() {Node* temp;while (front != NULL)  // while queue is not yet empty{temp = front;         // save address of front itemfront = front->next;  // reset pointer to next itemdelete temp;          // delete former front}
}
bool Queue::isempty() const { return items == 0; }
bool Queue::isfull() const { return items == qsize; }
int Queue::queuecount() const { return items; }
// Add item to queue
bool Queue::enqueue(const Item& item) {if (isfull()) return false;Node* add = new Node;  // create node// on failure, new throws std::bad_alloc exceptionadd->item = item;  // set node pointersadd->next = NULL;  // or nullptr;items++;if (front == NULL)  // if queue is empty,front = add;      // place item at frontelserear->next = add;  // else place at rearrear = add;          // have rear point to new nodereturn true;
}
// Place front item into item variable and remove from queue
bool Queue::dequeue(Item& item) {if (front == NULL) return false;item = front->item;  // set item to first item in queueitems--;Node* temp = front;   // save location of first itemfront = front->next;  // reset front to next itemdelete temp;          // delete former first itemif (items == 0) rear = NULL;return true;
}
// customer method
// when is the time at which the customer arrives
// the arrival time is set to when and the processing
// time set to a random value in the range 1 - 3
void Customer::set(long when) {processtime = std::rand() % 3 + 1;arrive = when;
}

main.cpp:

// bank.cpp -- using the Queue interface
// compile with queue.cpp
#include <cstdlib>  // for rand() and srand()
#include <ctime>    // for time()
#include <iostream>#include "queue.h"
const int MIN_PER_HR = 60;
bool newcustomer(double x);  // is there a new customer?
int main() {using std::cin;using std::cout;using std::endl;using std::ios_base;// setting things upstd::srand(std::time(0));  // random initializing of rand()cout << "Case Study: Bank of Heather Automatic Teller\n";cout << "Enter maximum size of queue: ";int qs;cin >> qs;Queue line(qs);  // line queue holds up to qs peoplecout << "Enter the number of simulation hours: ";int hours;  // hours of simulationcin >> hours;// simulation will run 1 cycle per minutelong cyclelimit = MIN_PER_HR * hours;  // # of cyclesdouble perhour = 1;  // number of customers per hour starts from 1double min_per_cust;  // average time between arrivalsmin_per_cust = MIN_PER_HR / perhour;Item temp;                // new customer datalong turnaways = 0;       // turned away by full queuelong customers = 0;       // joined the queuelong served = 0;          // served during the simulationlong sum_line = 0;        // cumulative line lengthint wait_time = 0;        // time until autoteller is freelong line_wait = 0;       // cumulative time in linedouble average_time = 0;  // average timewhile (perhour++ && average_time <= 1) {while (!line.isempty()) {line.dequeue(temp);}min_per_cust = MIN_PER_HR / perhour;for (int cycle = 0; cycle < cyclelimit; cycle++) {if (newcustomer(min_per_cust)) {if (line.isfull())turnaways++;else {customers++;temp.set(cycle);line.enqueue(temp);}}if (wait_time <= 0 && !line.isempty()) {line.dequeue(temp);wait_time = temp.ptime();line_wait += cycle - temp.when();served++;}if (wait_time > 0) wait_time--;sum_line += line.queuecount();}if (customers > 0) {average_time = (double)line_wait / served;cout << "customers accepted: " << customers << endl;cout << "  customers served: " << served << endl;cout << "         turnaways: " << turnaways << endl;cout << "average queue size: ";cout.precision(2);cout.setf(ios_base::fixed, ios_base::floatfield);cout << (double)sum_line / cyclelimit << endl;cout << " average wait time: " << average_time << " minutes\n";} elsecout << "No customers!\n";}cout << "When there comes " << perhour<< " people per hour, the average wait time will be about 1 minute.\n";cout << "Done!\n";return 0;
}
// x = average time, in minutes, between customers
// return value is true if customer shows up this minute
bool newcustomer(double x) { return (std::rand() * x / RAND_MAX < 1); }

实验过程中,队列最大数为10,模拟小时数为100,结果如下:

Case Study: Bank of Heather Automatic Teller
Enter maximum size of queue: 10
Enter the number of simulation hours: 100
customers accepted: 217customers served: 217turnaways: 0
average queue size: 0.00average wait time: 0.06 minutes
customers accepted: 522customers served: 522turnaways: 0
average queue size: 0.01average wait time: 0.07 minutes
customers accepted: 941customers served: 941turnaways: 0
average queue size: 0.01average wait time: 0.09 minutes
customers accepted: 1465customers served: 1465turnaways: 0
average queue size: 0.02average wait time: 0.10 minutes
customers accepted: 2078customers served: 2078turnaways: 0
average queue size: 0.04average wait time: 0.12 minutes
customers accepted: 2821customers served: 2821turnaways: 0
average queue size: 0.07average wait time: 0.15 minutes
customers accepted: 3640customers served: 3640turnaways: 0
average queue size: 0.10average wait time: 0.17 minutes
customers accepted: 4525customers served: 4525turnaways: 0
average queue size: 0.14average wait time: 0.19 minutes
customers accepted: 5534customers served: 5534turnaways: 0
average queue size: 0.20average wait time: 0.21 minutes
customers accepted: 6617customers served: 6617turnaways: 0
average queue size: 0.26average wait time: 0.24 minutes
customers accepted: 7780customers served: 7780turnaways: 0
average queue size: 0.35average wait time: 0.27 minutes
customers accepted: 9094customers served: 9094turnaways: 0
average queue size: 0.47average wait time: 0.31 minutes
customers accepted: 10427customers served: 10427turnaways: 0
average queue size: 0.60average wait time: 0.34 minutes
customers accepted: 11989customers served: 11989turnaways: 0
average queue size: 0.82average wait time: 0.41 minutes
customers accepted: 13588customers served: 13588turnaways: 0
average queue size: 1.02average wait time: 0.45 minutes
customers accepted: 15277customers served: 15277turnaways: 0
average queue size: 1.25average wait time: 0.49 minutes
customers accepted: 17118customers served: 17116turnaways: 0
average queue size: 1.55average wait time: 0.54 minutes
customers accepted: 19000customers served: 18998turnaways: 0
average queue size: 1.90average wait time: 0.60 minutes
customers accepted: 21012customers served: 21009turnaways: 0
average queue size: 2.39average wait time: 0.68 minutes
customers accepted: 23139customers served: 23136turnaways: 0
average queue size: 2.94average wait time: 0.76 minutes
customers accepted: 25374customers served: 25368turnaways: 0
average queue size: 3.59average wait time: 0.85 minutes
customers accepted: 27661customers served: 27653turnaways: 0
average queue size: 4.36average wait time: 0.95 minutes
customers accepted: 30018customers served: 30010turnaways: 1
average queue size: 5.32average wait time: 1.06 minutes
When there comes 25.00 people per hour, the average wait time will be about 1 minute.
Done!
6.Heather银行想知道,如果再开设一台ATM,情况将如何。请对模拟进行修改,以包含两个队列。假设当第一台ATM前的排队人数少于第二台ATM时,客户将排在第一队,否则将排在第二队。然后再找出要使平均等候时间为1分钟,每小时到达的客户数应该为多少(注意,这是一个非线性问题,即将ATM数量加倍,并不能保证每小时处理的客户数量也翻倍,并确保客户等候的时间少于1分钟)?

queue.h(未修改):

// queue.h -- interface for a queue
#ifndef QUEUE_H_
#define QUEUE_H_
// This queue will contain Customer items
class Customer {private:long arrive;      // arrival time for customerint processtime;  // processing time for customerpublic:Customer() { arrive = processtime = 0; }void set(long when);long when() const { return arrive; }int ptime() const { return processtime; }
};
typedef Customer Item;class Queue {private:// class scope definitions// Node is a nested structure definition local to this classstruct Node {Item item;struct Node* next;};enum { Q_SIZE = 10 };// private class membersNode* front;      // pointer to front of QueueNode* rear;       // pointer to rear of Queueint items;        // current number of items in Queueconst int qsize;  // maximum number of items in Queue// preemptive definitions to prevent public copyingQueue(const Queue& q) : qsize(0) {}Queue& operator=(const Queue& q) { return *this; }public:Queue(int qs = Q_SIZE);  // create queue with a qs limit~Queue();bool isempty() const;bool isfull() const;int queuecount() const;bool enqueue(const Item& item);  // add item to endbool dequeue(Item& item);        // remove item from front
};
#endif

queue.cpp(未修改):

// queue.cpp -- Queue and Customer methods
#include "queue.h"#include <cstdlib>  // (or stdlib.h) for rand()
// Queue methods
Queue::Queue(int qs) : qsize(qs) {front = rear = NULL;  // or nullptritems = 0;
}
Queue::~Queue() {Node* temp;while (front != NULL)  // while queue is not yet empty{temp = front;         // save address of front itemfront = front->next;  // reset pointer to next itemdelete temp;          // delete former front}
}
bool Queue::isempty() const { return items == 0; }
bool Queue::isfull() const { return items == qsize; }
int Queue::queuecount() const { return items; }
// Add item to queue
bool Queue::enqueue(const Item& item) {if (isfull()) return false;Node* add = new Node;  // create node// on failure, new throws std::bad_alloc exceptionadd->item = item;  // set node pointersadd->next = NULL;  // or nullptr;items++;if (front == NULL)  // if queue is empty,front = add;      // place item at frontelserear->next = add;  // else place at rearrear = add;          // have rear point to new nodereturn true;
}
// Place front item into item variable and remove from queue
bool Queue::dequeue(Item& item) {if (front == NULL) return false;item = front->item;  // set item to first item in queueitems--;Node* temp = front;   // save location of first itemfront = front->next;  // reset front to next itemdelete temp;          // delete former first itemif (items == 0) rear = NULL;return true;
}
// customer method
// when is the time at which the customer arrives
// the arrival time is set to when and the processing
// time set to a random value in the range 1 - 3
void Customer::set(long when) {processtime = std::rand() % 3 + 1;arrive = when;
}

main.cpp:

// bank.cpp -- using the Queue interface
// compile with queue.cpp
#include <cstdlib>  // for rand() and srand()
#include <ctime>    // for time()
#include <iostream>#include "queue.h"
const int MIN_PER_HR = 60;
bool newcustomer(double x);  // is there a new customer?
int main() {using std::cin;using std::cout;using std::endl;using std::ios_base;// setting things upstd::srand(std::time(0));  // random initializing of rand()cout << "Case Study: Bank of Heather Automatic Teller\n";cout << "Enter maximum size of queue: ";int qs;cin >> qs;Queue line1(qs);  // line1 queue holds up to qs peopleQueue line2(qs);  // line2 queue holds up to qs peoplecout << "Enter the number of simulation hours: ";int hours;  // hours of simulationcin >> hours;// simulation will run 1 cycle per minutelong cyclelimit = MIN_PER_HR * hours;  // # of cyclesdouble perhour = 1;  // number of customers per hour starts from 1double min_per_cust;  // average time between arrivalsmin_per_cust = MIN_PER_HR / perhour;Item temp;                // new customer datalong turnaways = 0;       // turned away by full queuelong customers = 0;       // joined the queuelong served = 0;          // served during the simulationlong sum_line = 0;        // cumulative line lengthint line1_size = 0;       // number of people in line1int line2_size = 0;       // number of people in line2int wait_time1 = 0;       // time until autoteller is free in line1int wait_time2 = 0;       // time until autoteller is free in line2long line_wait = 0;       // cumulative time in linedouble average_time = 0;  // average timewhile (perhour++ && average_time <= 1) {while (!line1.isempty()) {line1.dequeue(temp);}while (!line2.isempty()) {line2.dequeue(temp);}min_per_cust = MIN_PER_HR / perhour;for (int cycle = 0; cycle < cyclelimit; cycle++) {if (newcustomer(min_per_cust)) {if (line1.isfull() && line2.isfull())turnaways++;else if (line1_size < line2_size) {customers++;temp.set(cycle);line1.enqueue(temp);line1_size++;} else {customers++;temp.set(cycle);line2.enqueue(temp);line2_size++;}}if (wait_time1 <= 0 && !line1.isempty()) {line1.dequeue(temp);line1_size--;wait_time1 = temp.ptime();line_wait += cycle - temp.when();served++;}if (wait_time2 <= 0 && !line2.isempty()) {line2.dequeue(temp);line2_size--;wait_time2 = temp.ptime();line_wait += cycle - temp.when();served++;}if (wait_time1 > 0) wait_time1--;if (wait_time2 > 0) wait_time2--;sum_line += line1.queuecount() + line2.queuecount();}if (customers > 0) {average_time = (double)line_wait / served;cout << "customers accepted: " << customers << endl;cout << "  customers served: " << served << endl;cout << "         turnaways: " << turnaways << endl;cout << "average queue size: ";cout.precision(2);cout.setf(ios_base::fixed, ios_base::floatfield);cout << (double)sum_line / cyclelimit << endl;cout << " average wait time: " << average_time << " minutes\n";} elsecout << "No customers!\n";}cout << "When there comes " << perhour<< " people per hour, the average wait time will be about 1 minute.\n";cout << "Done!\n";return 0;
}
// x = average time, in minutes, between customers
// return value is true if customer shows up this minute
bool newcustomer(double x) { return (std::rand() * x / RAND_MAX < 1); }

实验过程中,队列最大数为10,模拟小时数为100,结果如下:

Case Study: Bank of Heather Automatic Teller
Enter maximum size of queue: 10
Enter the number of simulation hours: 100
customers accepted: 212customers served: 212turnaways: 0
average queue size: 0.00average wait time: 0.03 minutes
customers accepted: 520customers served: 520turnaways: 0
average queue size: 0.00average wait time: 0.06 minutes
customers accepted: 917customers served: 917turnaways: 0
average queue size: 0.01average wait time: 0.06 minutes
customers accepted: 1372customers served: 1372turnaways: 0
average queue size: 0.02average wait time: 0.07 minutes
customers accepted: 1987customers served: 1987turnaways: 0
average queue size: 0.03average wait time: 0.10 minutes
customers accepted: 2715customers served: 2715turnaways: 0
average queue size: 0.05average wait time: 0.11 minutes
customers accepted: 3471customers served: 3471turnaways: 0
average queue size: 0.07average wait time: 0.12 minutes
customers accepted: 4367customers served: 4367turnaways: 0
average queue size: 0.09average wait time: 0.13 minutes
customers accepted: 5368customers served: 5368turnaways: 0
average queue size: 0.13average wait time: 0.14 minutes
customers accepted: 6454customers served: 6454turnaways: 0
average queue size: 0.17average wait time: 0.16 minutes
customers accepted: 7639customers served: 7639turnaways: 0
average queue size: 0.22average wait time: 0.17 minutes
customers accepted: 8909customers served: 8909turnaways: 0
average queue size: 0.27average wait time: 0.18 minutes
customers accepted: 10292customers served: 10292turnaways: 0
average queue size: 0.33average wait time: 0.19 minutes
customers accepted: 11830customers served: 11830turnaways: 0
average queue size: 0.41average wait time: 0.21 minutes
customers accepted: 13347customers served: 13347turnaways: 0
average queue size: 0.48average wait time: 0.21 minutes
customers accepted: 15033customers served: 15033turnaways: 0
average queue size: 0.57average wait time: 0.23 minutes
customers accepted: 16837customers served: 16836turnaways: 0
average queue size: 0.67average wait time: 0.24 minutes
customers accepted: 18717customers served: 18716turnaways: 0
average queue size: 0.79average wait time: 0.25 minutes
customers accepted: 20775customers served: 20774turnaways: 0
average queue size: 0.91average wait time: 0.26 minutes
customers accepted: 22874customers served: 22873turnaways: 0
average queue size: 1.05average wait time: 0.28 minutes
customers accepted: 25038customers served: 25037turnaways: 0
average queue size: 1.20average wait time: 0.29 minutes
customers accepted: 27395customers served: 27394turnaways: 0
average queue size: 1.37average wait time: 0.30 minutes
customers accepted: 29826customers served: 29825turnaways: 0
average queue size: 1.54average wait time: 0.31 minutes
customers accepted: 32313customers served: 32312turnaways: 0
average queue size: 1.73average wait time: 0.32 minutes
customers accepted: 34782customers served: 34781turnaways: 0
average queue size: 1.90average wait time: 0.33 minutes
customers accepted: 37513customers served: 37511turnaways: 0
average queue size: 2.12average wait time: 0.34 minutes
customers accepted: 40250customers served: 40248turnaways: 0
average queue size: 2.33average wait time: 0.35 minutes
customers accepted: 43151customers served: 43149turnaways: 0
average queue size: 2.56average wait time: 0.36 minutes
customers accepted: 46116customers served: 46114turnaways: 0
average queue size: 2.80average wait time: 0.36 minutes
customers accepted: 49234customers served: 49232turnaways: 0
average queue size: 3.07average wait time: 0.37 minutes
customers accepted: 52400customers served: 52398turnaways: 0
average queue size: 3.35average wait time: 0.38 minutes
customers accepted: 55651customers served: 55648turnaways: 0
average queue size: 3.65average wait time: 0.39 minutes
customers accepted: 59012customers served: 59008turnaways: 0
average queue size: 3.97average wait time: 0.40 minutes
customers accepted: 62468customers served: 62464turnaways: 0
average queue size: 4.29average wait time: 0.41 minutes
customers accepted: 66015customers served: 66010turnaways: 0
average queue size: 4.62average wait time: 0.42 minutes
customers accepted: 69696customers served: 69691turnaways: 0
average queue size: 4.97average wait time: 0.43 minutes
customers accepted: 73509customers served: 73503turnaways: 0
average queue size: 5.38average wait time: 0.44 minutes
customers accepted: 77483customers served: 77476turnaways: 0
average queue size: 5.81average wait time: 0.45 minutes
customers accepted: 81552customers served: 81544turnaways: 0
average queue size: 6.24average wait time: 0.46 minutes
customers accepted: 85676customers served: 85668turnaways: 0
average queue size: 6.70average wait time: 0.47 minutes
customers accepted: 89893customers served: 89885turnaways: 0
average queue size: 7.18average wait time: 0.48 minutes
customers accepted: 94185customers served: 94177turnaways: 0
average queue size: 7.68average wait time: 0.49 minutes
customers accepted: 98572customers served: 98564turnaways: 0
average queue size: 8.22average wait time: 0.50 minutes
customers accepted: 103067customers served: 103058turnaways: 0
average queue size: 8.78average wait time: 0.51 minutes
customers accepted: 107697customers served: 107688turnaways: 0
average queue size: 9.38average wait time: 0.52 minutes
customers accepted: 112391customers served: 112382turnaways: 0
average queue size: 9.98average wait time: 0.53 minutes
customers accepted: 117190customers served: 117181turnaways: 0
average queue size: 10.67average wait time: 0.55 minutes
customers accepted: 122085customers served: 122075turnaways: 0
average queue size: 11.43average wait time: 0.56 minutes
customers accepted: 127075customers served: 127065turnaways: 0
average queue size: 12.17average wait time: 0.57 minutes
customers accepted: 132223customers served: 132212turnaways: 0
average queue size: 13.06average wait time: 0.59 minutes
customers accepted: 137410customers served: 137398turnaways: 0
average queue size: 14.04average wait time: 0.61 minutes
customers accepted: 142710customers served: 142697turnaways: 0
average queue size: 15.11average wait time: 0.63 minutes
customers accepted: 148126customers served: 148112turnaways: 0
average queue size: 16.21average wait time: 0.66 minutes
customers accepted: 153631customers served: 153617turnaways: 0
average queue size: 17.51average wait time: 0.68 minutes
customers accepted: 159249customers served: 159234turnaways: 0
average queue size: 19.50average wait time: 0.73 minutes
customers accepted: 164952customers served: 164936turnaways: 0
average queue size: 22.05average wait time: 0.80 minutes
customers accepted: 170746customers served: 170720turnaways: 0
average queue size: 24.75average wait time: 0.87 minutes
customers accepted: 176635customers served: 176603turnaways: 11
average queue size: 29.79average wait time: 1.01 minutes
When there comes 60.00 people per hour, the average wait time will be about 1 minute.
Done

C++ Primer Plus习题及答案-第十二章相关推荐

  1. C++ Primer Plus习题及答案-第十四章

    习题选自:C++ Primer Plus(第六版) 内容仅供参考,如有错误,欢迎指正 ! 第十四章- 代码重用笔记 复习题 1. 以A栏的类为基类时,B栏的类采用公有派生还是私有派生更合适 A B c ...

  2. C++ Primer Plus习题及答案-第十五章

    习题选自:C++ Primer Plus(第六版) 内容仅供参考,如有错误,欢迎指正 ! 友元类和嵌套类 RTTI和类型转换运算符 复习题 1. 下面建立友元的尝试有什么错误? a. class sn ...

  3. 深大uooc大学生心理健康章节答案第十二章

    一.单选题 (共 30.00 分) 自我管理能力指的是:( ) A. 顺利完成某种活动的心理特性),比如人际交往能力.观察力.想象力.组织能力 B. 某一专业.领域的知识和能力),比如开车,外语,编程 ...

  4. C++Primer第五版 习题答案 第十二章 动态内存

    12.1 b1有四个元素: b2被销毁: 12.2 strBlob.h #ifndef STRBLOB_H_ #define STRBLOB_H_#include<string> #inc ...

  5. 《C++ Primer》习题参考答案:第6章 - C++模块设计——函数

    专栏C++学习笔记 <C++ Primer>学习笔记/习题答案 总目录 https://blog.csdn.net/TeFuirnever/article/details/10070021 ...

  6. c++primer plus第六版第十二章第一题

    //h文件 #pragma once class cow {char name[20];char*hobby;double weight; public:cow();cow(const char*m, ...

  7. 工程伦理第十二章习题答案

    工程伦理 第十二章习题 工程伦理 1 选择题 2 讨论题 1 选择题 1-5 AABCD 6 BD 7 ABCD 8 ACD 9 BCD 10 ABCD 11-15 × × × × × 2 讨论题 1 ...

  8. 软件项目管理第4版课后习题[附解析]第十四章

    软件项目管理第4版课后习题[附解析]系列文章目录 第一章 第二章 第三章 第四章 第五章 第六章 第七章 第八章 第九章 第十章 第十一章 第十二章 第十三章 第十四章 第十五章 第十六章 期末复习题 ...

  9. java语言程序设计基础篇课后答案_《Java语言程序设计:基础篇》课后复习题答案-第十五章.pdf...

    <Java语言程序设计:基础篇>课后复习题答案-第十五章 Chapter15Graphics 1. Theycoordinateshouldincreaseandthexcoordinat ...

最新文章

  1. 服务器信号为970101,cDIN_EN_ISO_306.970101精选.pdf
  2. R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(双分类变量分组:色彩配置、形状配置)实战
  3. im即时通讯源码_IM消息ID技术专题(六):深度解密滴滴的高性能ID生成器(Tinyid)
  4. nessus rpm 安装_CentOS8.0下查看已安装的软件位置
  5. JEPaaS笔记||学习培训资料||案例视频 【全套】
  6. java 生成url_JAVA 通过URL生成水印图
  7. 数据安全架构设计与实战~如何加密结构化数据
  8. Springboot2学习博客
  9. 吴恩达深度学习2.1练习_Improving Deep Neural Networks_Regularization
  10. 一个JavaScript的小问题
  11. 仿微信选项卡主页面创建
  12. IIS出现server application error的解决办法
  13. Windows Server 2012R2 安装IIS 的详细配置
  14. m-bom,p-bom,e-bom 这是什么意思
  15. 利用ode45求解含控制量并且控制量为离散点的动力学方程
  16. VC浏览器相关的学习(六)(IDispEventImpl包装的主要方法)
  17. 亚马逊获20亿美元信用额度:有助新业务投资
  18. 统计学 多元线性回归
  19. git reflog 时光穿梭机
  20. 玩游戏跳出计算机内存不足怎么办,电脑内存不足怎么办?电脑内存不足的解决方法...

热门文章

  1. 圈地运动-组成面积大于0多边形
  2. 戴尔计算机显卡型号,戴尔笔记本电脑型号有哪些 戴尔笔记本电脑推荐【详解】...
  3. Android学习第三天 创建demo 电话拨号器
  4. [导入]补脾益气--四神汤
  5. 飞机黑匣子的数据要读取多久?
  6. MyBatis使用步骤及原理
  7. IPGUARD后台下发win10正版激活任务
  8. 几组数据的相关性python_属狗的几月出生最好
  9. IOS – OpenGL ES 图像马赛克圆点 GPUImagePolkaDotFilter
  10. 中国古代十三大神兽与十大妖仙