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.cpp
#include "cow.h"
Cow::Cow()
{
name[0] = '\0';
hobby = nullptr;
weight = 0.0;
}
Cow::Cow(const char* nm, const char* ho, double wt)
{
strncpy(name,nm,20);
if (strlen(nm) >= 20)
{
name[19] = '\0';
}
hobby = new char[strlen(ho) + 1];
strcpy(hobby, ho);
weight = wt;
}
Cow::Cow(const Cow& c)
{
strcpy(name,c.name);
hobby = new char[strlen(c.hobby) + 1];
strcpy(hobby, c.hobby);
weight = c.weight;
}
Cow::~Cow()
{
delete []hobby;
}
Cow& Cow::operator=(const Cow& c)
{
if (this == &c)
{
return *this;
}
delete []hobby;
hobby = new char[strlen(c.hobby) + 1];
strcpy(hobby, c.hobby);
strcpy(name, c.name);
weight = c.weight;
return *this;
}
void Cow::ShowCow() const
{
cout << "Name:" << name << " , Hobby:" << hobby << " , Weight:" << weight << endl;
}
main.cpp
Cow cow1;
Cow cow2("cow2", "piano", 70);
Cow cow3(cow2);
cow1 = cow2;
cow1.ShowCow();
cow2.ShowCow();
cow3.ShowCow();
2.通过完成下面的工作来改进string类声明(即将String1.h升级为String2.h)。
a.对+运算符进行重载,使之可将两个字符串合并为一个。
b.提供一个StringLow()成员函数,将字符串中所有的字母字符转换为小写(别忘了cctype系列字符函数)。
c.提供StringUp()成员函数,将字符串中所有字母字符转换为大写。
d.提供一个这样的成员函数,它接受一个char参数,返回该字符在字符串中出现的次数。
使用下面的程序来测试您的工作:
#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 << operator
cin >> s3; // overloaded >> operator
s2 = "My name is " + s3; // overloaded =, + operators
cout << s2 << ".\n";
s2 = s2 + s1;
s2.stringup(); // converts string to uppercase
cout << "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 lowercase
for (int i = 0; i < 3; i++)
{
if (ans == rgb[i]) // overloaded == operator
{
cout << "That's right!\n";
success = true;
break;
}
}
if (success)
break;
else
cout << "Try again!\n";
}
cout << "Bye\n";
return 0;
}
实现:
String2.h
#pragma once
#include <cctype>
#include <cstring>
#include <iostream>
using namespace std;
class String
{
private:
char* str; // pointer to string
int len; // length of string
static int num_strings; // number of objects
static const int CINLIM = 80; // cin input limit
public:
// constructors and other methods
String(const char* s); // constructor
String(); // default constructor
String(const String&); // copy constructor
~String(); // destructor
int length() const { return len; }
// overloaded operator methods
String& operator=(const String&);
String& operator=(const char*);
char& operator[](int i);
const char& operator[](int i) const;
// overloaded operator friends
friend bool operator<(const String& st, const String& st2);
friend bool operator>(const String& st1, 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);
// static function
static int HowMany();
//新增函数
friend String operator+(const char*s, const String& st);
String operator+(const String& st);
void StringLow();
void StringUp();
int Has(const char ch);
};
String2.cpp
#include "string2.h"
int String::num_strings = 0;
// static method
int String::HowMany()
{
return num_strings;
}
// class methods
String::String(const char* s) // construct String from C string
{
len = std::strlen(s); // set size
str = new char[len + 1]; // allot storage
std::strcpy(str, s); // initialize pointer
num_strings++; // set object count
}
String::String() // default constructor
{
len = 4;
str = new char[1];
str[0] = '\0'; // default string
num_strings++;
}
String::String(const String& st)
{
num_strings++; // handle static member update
len = st.len; // same length
str = new char[len + 1]; // allot space
std::strcpy(str, st.str); // copy string to new location
}
String::~String() // necessary destructor
{
--num_strings; // required
delete []str; // required
}
// overloaded operator methods
// assign a String to a String
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;
}
// assign a C string to a String
String& String::operator=(const char* s)
{
delete[] str;
len = std::strlen(s);
str = new char[len + 1];
std::strcpy(str, s);
return *this;
}
// read-write char access for non-const String
char& String::operator[](int i)
{
return str[i];
}
// read-only char access for const String
const char& String::operator[](int i) const
{
return str[i];
}
// overloaded operator friends
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 < st1;
}
bool operator==(const String& st1, const String& st2)
{
return (std::strcmp(st1.str, st2.str) == 0);
}
// simple String output
ostream& operator<<(ostream& os, const String& st)
{
os << st.str;
return os;
}
// quick and dirty String input
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, const String& st)
{
String temp;
temp.len = strlen(s) + st.len;
temp.str = new char[temp.len + 1];
strcpy(temp.str, s);
strcat(temp.str, st.str);
return temp;
}
String String::operator+(const String& st)
{
String temp;
temp.len = len + st.len;
temp.str = new char[temp.len + 1];
strcpy(temp.str, str);
strcat(temp.str, st.str);
return temp;
}
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(const char ch)
{
int count = 0;
for (int i = 0; i < len; i++)
{
if (str[i] == ch)
{
count++;
}
}
return count;
}
3.新编写程序清单10.7和程序清单10.8描述的stock类,使之使用动态分配的内存,而不是string类对象来存储股票名称。另外,使用重载的operator<<()定义代替show()成员函数。再使用程序清单10.9测试新的定义程序。
实现:
Stock1.h
#pragma once
#include <iostream>
#include <cstring>
using namespace std;
class Stock
{
private:
char* company;//original:string company
int shares;
double share_val;
double total_val;
void set_tot() { total_val = shares * share_val; }
public:
Stock(); // default constructor
Stock(const char* co, 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);
//void show()const;
const Stock& topval(const Stock& s) const;
friend ostream& operator<<(ostream &os, const Stock&s);
};
Stock1.cpp
#include "Stock1.h"
// constructors
Stock::Stock() // default constructor
{
company = nullptr;//delete可以释放空指针
shares = 0;
share_val = 0.0;
total_val = 0.0;
}
Stock::Stock(const char* co, long n /*= 0*/, double pr /*= 0.0*/)
{
company = new char[strlen(co) + 1];
strcpy(company, co);
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();
}
// 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();
}
//void Stock::show() const
//{
// using std::cout;
// using std::ios_base;
// // set format to #.###
// ios_base::fmtflags orig =
// cout.setf(ios_base::fixed, ios_base::floatfield);
// std::streamsize prec = cout.precision(3);
//
// cout << "Company: " << company
// << " Shares: " << shares << '\n';
// cout << " Share Price: $" << share_val;
// // set format to #.##
// cout.precision(2);
// cout << " Total Worth: $" << total_val << '\n';
//
// // restore original format
// cout.setf(orig, ios_base::floatfield);
// cout.precision(prec);
//}
const Stock& Stock::topval(const Stock& s) const
{
if (s.total_val > total_val)
return s;
else
return *this;
}
ostream& operator<<(ostream& os, const Stock& s)
{
cout << "company:" << s.company <<", hares:" << s.shares << ", share_val:" << s.share_val<< ", total_val:" << s.total_val << endl;
return os;
}
main.cpp
#include "Stock1.h"
const int STKS = 4;
int main()
{
// create an array of initialized objects
Stock stocks[STKS] = {
Stock("NanoSmart", 12, 20.0),
Stock("Boffo Objects", 200, 2.0),
Stock("Monolithic Obelisks", 130, 3.25),
Stock("Fleep Enterprises", 60, 6.5)
};
std::cout << "Stock holdings:\n";
int st;
for (st = 0; st < STKS; st++)
cout << stocks[st];
// set pointer to first element
const Stock* top = &stocks[0];
for (st = 1; st < STKS; st++)
top = &top->topval(stocks[st]);
// now top points to the most valuable holding
std::cout << "\nMost valuable holding:\n";
cout << *top;
return 0;
}
4.请看下面程序清单10.10定义的Stack类的变量:
#pragma once
typedef unsigned long Item;
class Stack
{
private:
enum { MAX = 10 }; // constant specific to class
Item items[MAX]; // holds stack items
int top; // index for top stack item
public:
Stack();
bool isempty() const;
bool isfull() const;
// push() returns false if stack already is full, true otherwise
bool push(const Item& item); // add item to stack
// pop() returns false if stack already is empty, true otherwise
bool pop(Item& item); // pop top into item
};
正如私有成员声明的,这个类使用动态分配的数组来保存栈项。请重新编写方法,以适应这种新的表示法,并编写一个程序来演示所有的方法,包括复制构造函数和赋值构造函数。
实现:
stack.h
#pragma once
typedef unsigned long Item;
class Stack
{
private:
enum { MAX = 10 }; // constant specific to class
Item* pitems;
int size;
int top; // index for top stack item
public:
Stack(int n = MAX);
Stack(const Stack& st);
~Stack();
bool isempty() const;
bool isfull() const;
// push() returns false if stack already is full, true otherwise
bool push(const Item& item); // add item to stack
// pop() returns false if stack already is empty, true otherwise
bool pop(Item& item); // pop top into item
Stack& operator=(const Stack& st);
};
stack.cpp
#include "stack.h"
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;
}
else
return false;
}
bool Stack::pop(Item& item)
{
if (top > 0)
{
item = pitems[--top];
return true;
}
else
return false;
}
Stack::Stack(int n)
{
pitems = new Item[n];
size = n;
top = 0;
}
Stack::Stack(const Stack& st)
{
pitems = new Item[st.size];
for (int i = 0; i < st.size; i++)
{
pitems[i] = st.pitems[i];
}
size = st.size;
top = st.top;
}
Stack::~Stack()
{
delete []pitems;
}
Stack& Stack::operator=(const Stack& st)
{
if (this == &st)
{
return *this;
}
delete []pitems;
pitems = new Item[st.size];
for (int i = 0; i < st.size; i++)
{
pitems[i] = st.pitems[i];
}
size = st.size;
top = st.top;
return *this;
}
main.cpp
#include "stack.h"
const int SIZE = 5;
int main()
{
Stack st(SIZE);
Item item;
for (int i = 0; i < SIZE; i++)
{
cout << "Enter number you want to push to stack:" << endl;
cin >> item;
while (cin.get() != '\n');
st.push(item);
}
Stack st_new(st);
for (int i = 0; i < SIZE; i++)
{
st_new.pop(item);
cout << item << " is poped!" << endl;
}
return 0;
}