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 {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
};
#endif
Cow.cpp:
#include "Cow.h"
#include <iostream>
#include <cstring>
using namespace std;
Cow::Cow(){name[0] = '\0';hobby = nullptr;weight = 0.0;
}
Cow::Cow(const char * nm, const char * ho, double wt){strncpy(name, nm, 20);int len2 = strlen(ho);hobby = new char[len2 + 1];strcpy(hobby, ho);weight = wt;
}
Cow::Cow(const Cow &c){strncpy(name, c.name, 20);int len2 = strlen(c.hobby);hobby = new char[len2 + 1];strcpy(hobby, c.hobby);weight = c.weight;
}
Cow::~Cow(){delete[] hobby;
}
Cow & Cow::operator=(const Cow & c){if(this == &c)return *this;strncpy(name, c.name, 20);delete[] hobby;int len2 = strlen(c.hobby);hobby = new char[len2 + 1];strcpy(hobby, c.hobby);weight = c.weight;return *this;
}
void Cow::ShowCow() const{cout << "name:" << name;cout << endl;cout << "hobby:" << hobby;cout << endl;cout << "weight:" << weight;cout << endl;cout << endl;
}
main.cpp:
#include "Cow.h"
#include <iostream>/* run this program using the console pauser or add your own getch, system("pause") or input loop */int main(int argc, char** argv) {//c1调用构造函数Cow(const char * nm, const char * ho, double wt); Cow c1("xiaoyu", "eating", 100);c1.ShowCow();//c2调用复制构造函数Cow(const Cow &c); Cow c2 = c1;c2.ShowCow();//c3调用赋值运算符重载函数Cow & operator=(const Cow & c); Cow c3;c3 = c2;c3.ShowCow();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
String.h:
#ifndef STRING_H
#define STRING_H#include <iostream>
using std::ostream;
using std::istream;
class String{private:char *str;int len;//static int num_strings;public:static const int CINLIM = 80;//constructors and other methodsString();String(const char*);String(const String &);~String();int length()const{return len;}void stringlow();void stringup();int has(char c)const;//overload operator methodsString operator+(String &);
// String operator+(const char *s) const;String &operator=(const String &);String &operator=(const char *);char &operator[](int);const char &operator[](int)const;//overload operator friends//friend bool operator<(const String &, const String &);//friend bool operator>(const String &, const String &);friend bool operator==(const String &, const String &);friend String operator+(const char *, String &);friend ostream &operator<<(ostream &, const String &);friend istream &operator>>(istream &, String &);//static function//static int HowMany();
};
#endif
String.cpp:
#include "String.h"
#include <cstring>
#include <cctype>//constructors and other methods
String::String(){str = new char[1];str[0] = '\0';len = 0;
}
String::String(const char* s){len = strlen(s);str = new char[len + 1];strcpy(str, s);
}
String::String(const String &s){len = s.len;str = new char[len + 1];strcpy(str, s.str);
}
String::~String(){delete[] str;
}
void String::stringlow(){for(int i = 0; i < len; i++){str[i] = tolower(str[i]);}
}
void String::stringup(){for(int i = 0; i < len; i++){str[i] = toupper(str[i]);}
}
int String::has(char c)const{int ch = 0;for(int i = 0; i < len; i++){if(str[i] == '\n'){break;}if(str[i] == 'c'){ch++;}}return ch;
}//overload operator methods
String String::operator+(String &s){int lengt = len + s.len;char *temp = new char[lengt + 1];strcpy(temp, str);strcat(temp, s.str);String result = temp;//调用构造函数 delete[] temp;return result;
}
//String String::operator+(const char *s) const {
// String tmp = s;
// String sum = *this + tmp;
// return sum;
//}
String &String::operator=(const String &st){if(this == &st)return *this;delete[] str;len = strlen(st.str);str = new char[len + 1];strcpy(str, st.str);return *this;
}
String &String::operator=(const char *s){delete[] str;len = strlen(s);str = new char[len + 1];strcpy(str, s);return *this;
}
char &String::operator[](int i){return str[i];
}
const char &String::operator[](int i)const{return str[i];
}//overload operator friends
bool operator==(const String &str1, const String &str2){return (strcmp(str1.str, str2.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 *s, String &ss){return String(s) + ss;
}
main.cpp:
#include "String.h"
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */int main(int argc, char** argv) {String s1(" and I am a C++ student.");//constructor String s2 = "Please enter your name: ";//overloaded = operatorString s3;cout << s2; // overloaded << operatorcin >> s3; // overloaded >> operators2 = "My name is " + s3; // overloaded =, + operators(friend)cout << s2 << ".\n";// overloaded << operators2 = s2 + s1;// overloaded =, + operatorss2.stringup(); // converts string to uppercasecout << "The string\n" << s2 << "\ncontains " << s2.has('A')<< " 'A' characters in it.\n";// overloaded << operators1 = "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;
}
输出结果如下:
3. 新编写程序清单10.7和程序清单10.8描述的Stock类,使之使用动态分配的内存,而不是string类对象来存储股票名称。另外,使用重载的operator<<()定义代替show()成员函数。再使用程序清单10.9测试新的定义程序。
Stock.h:
#ifndef STOCK_H
#define STOCK_H
#include <iostream>
using namespace std;
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, double pr);~Stock(); // do-nothing destructorvoid buy(long num, double price);void sell(long num, double price);void update(double price);friend ostream& operator<<(ostream& os, const Stock& st);const Stock& topval(const Stock& s) const;
};
#endif
Stock.cpp:
#include "stock.h"
#include <cstring>
#include <iostream>
using namespace std;
Stock::Stock() {company = new char[8];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[strlen(co) + 1];strcpy(company, co);if(n < 0) {cout << "Number of shares can't be negative;"<< company << "shares set to 0.\n";shares =0;} elseshares = n;share_val = pr;set_tot();
}
Stock::~Stock(){delete[] company;
}
void Stock::buy(long num, double price) {if (num < 0) {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) {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();
}
ostream& operator<<(ostream& os, const Stock& st) {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;
}
main.cpp:
#include <iostream>
#include "stock.h"
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
const int STKS = 4;
int main(int argc, char** argv) {Stock stocks[STKS] = {Stock("NanoSmart", 12, 20.0),Stock("Boffo objects", 200, 2.0),Stock("Monolithic belisks", 130, 3.25),Stock("Fleep Enterprises", 60, 6.5),};cout << "Stock holdings:\n";int st;for(st = 0; st < STKS; st++){cout << stocks[st];}const Stock *top = &stocks[0];for(st = 1; st < STKS; st++){top = &top->topval(stocks[st]);}cout << "\nMost valuable holding:\n";cout << *top;return 0;
}
输出结果:
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:
#ifndef STACK_H
#define STACK_H
#include <iostream>
using namespace std;
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(Item* it, int s, int t);Stack(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 ostream &operator<<(ostream &, const Stack &);
};
#endif
Stack.cpp:
#include "Stack.h"
Stack::Stack(int n){size = MAX;top = 0;pitems = new Item[size];for(int i = 0; i < size; i++)pitems[i] = 0;
}
Stack::Stack(Item* it, int s, int t){size = s;top = t;pitems = new Item[s];for(int i = 0; i < size; i++)pitems[i] = it[i];
}
Stack::Stack(const Stack & st){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;size = 0;top = 0;
}
bool Stack::isempty() const{if(top == 0)return true;elsereturn false;
}
bool Stack::isfull() const{if(top == MAX)return true;elsereturn false;
}
bool Stack::push(const Item & item){if(this->Stack::isfull())return false;size += 1;top++;pitems[top] = item;
}
bool Stack::pop(Item & item){if(this->isempty())return false;size -= 1;item = pitems[top];top--;
}
Stack & Stack::operator=(const Stack & st){if(this == &st)return *this;size = st.size;top = st.top;delete[] pitems;pitems = new Item[size];for(int i = 0; i < size; i++)pitems[i] = st.pitems[i];return *this;
}
ostream &operator<<(ostream &os, const Stack &s){for(int i = 0; i < s.size; i++)os << s.pitems[i] << endl;return os;
}
main.cpp:
#include <iostream>
#include <cctype>
#include "Stack.h"
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */int main(int argc, char** argv) {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;
}
输出如下: