Answers to Exercises in "New Standard C++ Programming" Chapter 11-Chapter 20 Guo Wei

Answers to Exercises in "New Standard C++ Programming"
Chapter 11 - Chapter 20
Guo Wei
Chapter 11 Exercises
1. What are the shortcomings of structured programming? How can object-oriented programming improve these deficiencies?
2. Which of the following statements is correct:
A) Each object has the implementation code of the member function inside
B) A private member function of a class cannot access the private member variables of this class
C) The member functions of the class can call each other
D) When writing a class, at least one member function must be written
#C
3. Which of the following definitions of class A is correct?
A) class A {
private:
int v;
public :
void Func() { }
}
B) class A {
int v; A * next;
void Func() { }
};
C) class A {
int v;
public:
void Func();
};
A::void Func() { }
D)class A {
int v;
public:
A next;
void Func() { }};
#B
4. Assume the following class A:
class A {
public:
int func(int a) { return a * a; }
};
Which of the following program fragments is incorrect?
A) A a; a.func(5);
B) A * p = new A; p->func(5);
C) A a; A & r = a; r.func(5);
D) A a,b; if( a != b) a.func(5);
#D
5.以下程序,哪个是不正确的?
A) int main(){
class A { int v; };
A a; a.v = 3; return 0;
}
B) int main() {
class A { public: int v; A * p; };
A a; a.p = & a; return 0;
}
C)int main() {
class A { public:
int v; };
A * p = new A;
p->v = 4; delete p;
return 0;
}
D) int main() {
class A { public: int v; A * p; };
A a; a.p = new A; delete a.p;
return 0;
}
#A
6. 实现一个学生信息处理程序。输入:姓名,年龄,学号(整数),第一学年平均成绩,第二学年平
均成绩,第三学年平均成绩,第四学年平均成绩。输出:姓名,年龄,学号,四年平均成绩。例如:
输入:Tom,18,7817,80,80,90,70输出:Tom,18,7817,80
要求实现一个代表学生的类,并且所有成员变量都应该是私有的。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
class CStudent
{
private:
int age;
int id;
char name[20];
int averageScore[4];
public:
int average() {
int sum = 0;
for( int i = 0;i < 4; ++ i)
sum += averageScore[i];
return sum/4;
}
void printInfo() {
printf("%s,%d,%d,%d",name,age,id,average());
}
void readInfo() {
char buf[110];
cin.getline(buf,100);
char * p = strchr(buf,',');
p[0] = 0;
strcpy( name,buf);
sscanf(p + 1, "%d,%d,%d,%d,%d,%d",&id,&age,
averageScore,averageScore+1,averageScore+2,averageScore+3);
}
};
int main()
{CStudent s;
s.readInfo();
s.printInfo();
return 0;
} Chapter 12 Exercises
1. Which of the following statements is correct:
A) A class must have a no-argument constructor
B) The return value type of the constructor is void
C) A class can only define one destructor, but can define multiple constructors
D) A class can only define one constructor, but can define multiple destructors
#C
2. For objects generated by the new operator
A) Automatically destructed at the end of the program
B) It can only be destructed when the delete operation is performed
C) Automatically destruct when the function containing the new statement returns
D) It will be destructed when the delete operation is performed. If the delete operation is not performed, it will be automatically destructed at the end of the program
#B
3. If the return value of a function is an object, when the function is called, the returned object
A) is initialized via the copy constructor
B) is initialized via a parameterless constructor
C) Which constructor to initialize depends on how the return statement in the function is written
D) does not require initialization
#A
4. Which of the following statements is correct:
A) Any other member function of the same class can be called in a static member function
B) const member functions cannot act on non-const objects
C) The this pointer cannot be used in static member functions
D) Each object has its own copy of static member variables
#C
5. Which of the following statements about the this pointer is incorrect:
A) The this pointer cannot be used inside a const member function
B) The this pointer inside the member function points to the object on which the member function acts.
C) The this pointer can be used inside the constructor
D) The this pointer can be used inside the destructor
#A
6. Please write the output of the following program: class CSample {
int x;
public:
CSample() { cout << "C1" << endl; }
CSample(int n ) {
x = n;
cout << "C2,x=" << n << endl; }
};
int main(){
CSample array1[2];
CSample array2[2] = {6,8};
CSample array3[2] = {12};
CSample * array4 = new CSample[3];
return 0;
}
/*
C1
C1
C2,x=6
C2,x=8
C2,x=12
C1
C1
C1
C1
*/
7. Please write down the running result of the following program:
#include <iostream>
using namespace std;
class Sample{
public:
int v;
Sample() { };
Sample(int n):v(n) { };
Sample( const Sample & x) { v = 2 + x.v ; }
};
Sample PrintAndDouble( Sample o) {cout << o.v;
ov = 2 * ov;
return o;
}
int main() {
Sample a(5);
Sample b = a;
Sample c = PrintAndDouble( b );
cout << endl;
cout << c.v << endl;
Sample d;
d = a;
cout << d.v ;
}
/*
9
22 (20 is also correct)
5
*/
8. The output of the following program is
4,6
Please fill in the blank:
class A {
int val;
public:
A( int n) { val = n; }
int GetVal() { return val;}
};
class B: public A {
private:
int val;
public:
B(int n):______________{ }
int GetVal() { return val;}
};
int main() {
B b1(2);cout<<b1.GetVal()<< ","
<< b1.A::GetVal()<< endl;
return 0;
}
/*
val(2*n),A(3*n)
*/
9. The output of the following program is:
0
5
Please fill in the blank:
class A {
public:
int val;
A(_________________ ){ val = n; };
________________ GetObj() {
return _________________;
}
};
int main() {
A a;
cout <<a.val << endl;
a.GetObj() = 5;
cout << a.val << endl;
return 0;
}
/*
int n = 0
int &
val
or:
int n = 0
A &
*this
*/
10. The output of the following program is: 10
Please complete the member functions of the Sample class. Member variables cannot be added.
#include <iostream>
using namespace std;
class Sample{
public:
int v;
Sample(int n):v(n) { };
};
int main() {
Sample a(5);
Sample b = a;
cout << b.v ;
return 0;
}
/*
Sample(Sample & a):v(2 * a.v) { }
*/
11. The output of the following program is:
5,5
5,5
Please fill in the blank
#include <iostream>
using namespace std;
class Base {
public:
int k;
Base(int n):k(n) { }
};
class Big {
public:
int v; Base b;
Big ________________ { }
Big ________________{ }
};
int main() {
Big a1(5);
Big a2 = a1;cout << a1.v << "," << a1.b.k << endl;
cout << a2.v << "," << a2.b.k << endl;
return 0;
}
/*
(int n):v(n),b(n)
(Big & x):v(x.v),b(x.v)
*/
12. Complete the first phase of the homework mentioned in the appendix "World of Warcraft Homework".
// by Guo Wei
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define WARRIOR_NUM 5
/*
char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
The Red Command creates warriors in the order of iceman , lion , wolf , ninja and dragon .
蓝方司令部按照 lion dragon ninja iceman wolf 的顺序制造武士。
*/
class CHeadquarter;
class CWarrior
{
private:
CHeadquarter * pHeadquarter;
int nKindNo; // 武士的种类编号 0 dragon 1 ninja 2 iceman 3 lion 4 wolf
int nNo;
public:
static char * Names[WARRIOR_NUM];
static int InitialLifeValue [WARRIOR_NUM];
CWarrior( CHeadquarter * p,int nNo_,int nKindNo_ );
void PrintResult(int nTime);
};
class CHeadquarter
{ private:
int nTotalLifeValue;
bool bStopped;
int nTotalWarriorNum;
int nColor;
int nCurMakingSeqIdx; // Which number is the current warrior in the manufacturing sequence
int anWarriorNum[WARRIOR_NUM]; // store the number of each warrior
CWarrior * pWarriors[1000];
public:
friend class CWarrior;
static int MakingSeq[2][WARRIOR_NUM]; // Warrior's making sequence sequence
void Init(int nColor_, int lv);
~ CHeadquarter () ;
int Produce(int nTime);
void GetColor( char * szColor);
};
CWarrior:: CWarrior( CHeadquarter * p,int nNo_,int nKindNo_ ) {
nNo = nNo_;
nKindNo = nKindNo_;
pHeadquarter = p;
}
void CWarrior:: PrintResult(int nTime)
{
char szColor[20];
pHeadquarter-> GetColor(szColor);
printf("%03d %s %s %d born with strength %d,%d %s in %s headquarter\n" ,
nTime, szColor, Names[nKindNo], nNo,
InitialLifeValue[nKindNo],
pHeadquarter->anWarriorNum[nKindNo],Names[nKindNo],szColor);
}
void CHeadquarter:: Init(int nColor_, int lv)
{
nColor = nColor_;
nTotalLifeValue = lv;nTotalWarriorNum = 0;
bStopped = false;
nCurMakingSeqIdx = 0;
for( int i = 0;i < WARRIOR_NUM;i ++ )
anWarriorNum[i] = 0;
}
CHeadquarter::~ CHeadquarter () {
for( int i = 0;i < nTotalWarriorNum;i ++ )
delete pWarriors[i];
}
int CHeadquarter:: Produce(int nTime)
{
if( bStopped )
return 0;
int nSearchingTimes = 0;
while( CWarrior::InitialLifeValue[MakingSeq[nColor][nCurMakingSeqIdx]] >
nTotalLifeValue &&
nSearchingTimes < WARRIOR_NUM ) {
nCurMakingSeqIdx = ( nCurMakingSeqIdx + 1 ) % WARRIOR_NUM ;
nSearchingTimes ++;
}
int nKindNo = MakingSeq[nColor][nCurMakingSeqIdx];
if( CWarrior::InitialLifeValue[nKindNo] > nTotalLifeValue ) {
bStopped = true;
if( nColor == 0)
printf("%03d red headquarter stops making warriors\n",nTime);
else
printf("%03d blue headquarter stops making warriors\n",nTime);
return 0;
}
nTotalLifeValue -= CWarrior::InitialLifeValue[nKindNo];
nCurMakingSeqIdx = ( nCurMakingSeqIdx + 1 ) % WARRIOR_NUM ;
pWarriors[nTotalWarriorNum] = new CWarrior( this,nTotalWarriorNum+1,nKindNo);
anWarriorNum[nKindNo]++;
pWarriors[nTotalWarriorNum]-> PrintResult(nTime);nTotalWarriorNum ++;
return 1;
}
void CHeadquarter:: GetColor( char * szColor)
{
if( nColor == 0)
strcpy(szColor,"red");
else
strcpy(szColor,"blue");
}
char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
int CWarrior::InitialLifeValue [WARRIOR_NUM];
int CHeadquarter::MakingSeq[2][WARRIOR_NUM] = { { 2,3,4,1,0 },{3,0,1,2,4} }; // Two headquarters warriors
sequence of crafting
int main()
{
int t;
int m;
CHeadquarter RedHead,BlueHead;
scanf("%d",&t);
int nCaseNo = 1;
while ( t -- ) {
printf("Case:%d\n",nCaseNo++);
scanf("%d",&m);
for( int i = 0;i < WARRIOR_NUM;i ++ )
scanf("%d", & CWarrior::InitialLifeValue[i]);
RedHead. Init(0,m);
BlueHead. Init(1,m);
int nTime = 0;
while( true) {
int tmp1 = RedHead. Produce(nTime);
int tmp2 = BlueHead. Produce(nTime);
if( tmp1 == 0 && tmp2 == 0)
break;nTime ++;
}
}
return 0;
} Chapter 13 Exercises
If the operator "[]" is overloaded as a member operator (that is, a member function) of a class, the number of parameters of the member function is:
A) 0 B) 1 C) 2 D) 3
#B
2. If the operator "
* ” is overloaded as a member operator (that is, a member function) of a certain class, then the number of parameters of the member function is:
A) 0 B) 1 C) 2 D) 0 1 can be
#D
3. The output of the following program is:
3+4i
5+6i
Please complete the member functions of the Complex class. Member variables cannot be added.
#include <iostream>
#include <cstring>
using namespace std;
class Complex {
private:
double r,i;
public:
void Print() {
cout << r << "+" << i << "i" << endl;
}
};
int main() {
Complex a;
a = "3+4i"; a.Print();
a = "5+6i"; a.Print();
return 0;
}
/*
Complex(const char * s = NULL ) {
if( s ) {
int len = strlen(s);
char * tmp = new char[len+1];
strcpy( tmp,s);char * p = strchr(tmp,'+');
p[0] = 0;
tmp[len-1] = 0;
r = atof(s);
i = atof(p+1);
delete [] tmp;
}
else
r = i = 0;
}
or
Complex():r(0),i(0) { }
Complex & operator = (const char * s)
{
if( s ) {
int len = strlen(s);
char * tmp = new char[len+1];
strcpy( tmp,s);
char * p = strchr(tmp,'+');
p[0] = 0;
tmp[len-1] = 0;
r = atof(s);
i = atof(p+1);
delete [] tmp;
}
else
r = i = 0;
return * this;
}
*/
4. The MyInt class below has only one member variable. Part of the code inside the MyInt class is hidden. Assuming the following program compiles successfully,
And the output is:
4,1
Please write the hidden part. (The content you write must be able to be put into the MyInt class, and the member function of MyInt is not allowed to use
static variable).
#include <iostream>
using namespace std;class MyInt {
int nVal;
public:
MyInt( int n) { nVal = n ;}
int ReturnVal() { return nVal;}
……………………
};
int main () {
MyInt objInt(10);
objInt-2-1-3;
cout << objInt.ReturnVal();
cout <<",";
objInt-2-1;
cout << objInt.ReturnVal();
return 0;
}
/*
MyInt & operator-(int n) {
nVal -= n;
return * this;
}
*/
5. The output of the following program is:
(4,5)
(7,8)
Please fill in the blank:
#include <iostream>
using namespace std;
class Point {
private:
int x;
int y;
public:
Point(int x_,int y_ ):x(x_),y(y_) { };
__________________________________;
};
_____ operator << ( ______, const Point & p){
___________________________________;
return _________________;}
int main(){
cout << Point(4,5) << Point(7,8); return 0;}
/*
friend ostream & operator<<(ostream & ,const Point & p);
ostream &
ostream & o
o << "(" << p.x << "," << p.y << ")"
o
*/
6. Write a two-dimensional array class Array2, so that the output of the following program is:
0,1,2,3,
4,5,6,7,
8,9,10,11,
next
0,1,2,3,
4,5,6,7,
8,9,10,11,
program:
#include <iostream>
using namespace std;
int main() {
Array2 a(3,4);
int i,j;
for( i = 0;i < 3; ++i )
for( j = 0; j < 4; j ++ )
a[i][j] = i * 4 + j;
for( i = 0;i < 3; ++i ) {
for( j = 0; j < 4; j ++ ) {
cout << a(i,j) << ",";
}
cout << endl;
}
cout << "next" << endl;
Array2 b;
b = a;
for( i = 0;i < 3; ++i ) {
for( j = 0; j < 4; j ++ ) {
cout << b[i][j] << ",";}
cout << endl;
}
return 0;
}
/*
class Array2
{
private:
int * buf;
int row,col; //The array is row row, col column
public:
Array2(int r,int c):row(r),col(c),buf(new int[r*c+2]) { }
Array2():buf(new int[2]),row(0),col(0) { }
//The constructor ensures that buf will not be NULL, so you don't have to consider the special case of buf == NULL, troublesome
//Allocate more space, it doesn't matter
~Array2() {
delete [] buf;
}
int * operator [](int i) const {
return buf + i * col;
}
void duplicate(const Array2 & a) {
if( a.row == 0 || a.col == 0 )
row = col = 0; // It doesn't matter if the space is not reclaimed temporarily
else {
if( row * col < a.row * a.col ) { //The space is not big enough to reallocate the space
delete [] buf;
buf = new int[a.row*a.col];
}
memcpy(buf,a.buf,sizeof(int)*a.row * a.col);
row = a.row;
col = a.col;
}
}
Array2 & operator = ( const Array2 & a ) {
if( a.buf == buf )return * this;
duplicate(a);
return * this;
}
Array2(const Array2 & a):buf(new int[2]),row(0),col(0) {
duplicate(a);
}
int & operator() ( int r,int c) const {
return buf[r * col + c];
}
};
*/
7. Write a MyString class so that the output of the following program is:
1. abcd-efgh-abcd-
2. abcd-
3.
4. abcd-efgh-
5. efgh-
6. c
7. abcd-
8. ijAl-
9. ijAl-mnop
10. qrst-abcd-
11. abcd-qrst-abcd- uvw xyz
about
big
me
take
abcd
qrst-abcd-
program:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
using namespace std;int CompareString( const void * e1,
const void * e2) {
MyString * s1 = (MyString * ) e1;
MyString * s2 = (MyString * ) e2;
if( * s1 < *s2 ) return -1;
else if( *s1 == *s2) return 0;
else if( *s1 > *s2 ) return 1;
}
main() {
MyString s1("abcd-"),s2,
s3("efgh-"),s4(s1);
MyString SArray[4] =
{"big","me","about","take"};
cout << "1. " << s1 << s2 << s3<< s4<< endl;
s4 = s3; s3 = s1 + s3;
cout << "2. " << s1 << endl;
cout << "3. " << s2 << endl;
cout << "4. " << s3 << endl;
cout << "5. " << s4 << endl;
cout << "6. " << s1[2] << endl;
s2 = s1; s1 = "ijkl-";
s1[2] = 'A' ;
cout << "7. " << s2 << endl;
cout << "8. " << s1 << endl;
s1 += "mnop";
cout << "9. " << s1 << endl;
s4 = "qrst-" + s2;
cout << "10. " << s4 << endl;
s1 = s2 + s4 + " uvw " + "xyz";
cout << "11. " << s1 << endl;
qsort(SArray,4,sizeof(MyString),
CompareString);
for( int i = 0;i < 4;++i )
cout << SArray[i] << endl;
//Output the substring of s1 starting from subscript 0 with a length of 4
cout << s1(0,4) << endl;
//Output the substring of s1 whose length is 10 starting from subscript 5 cout << s1(5,10) << endl;
}
/*
class MyString
{
private:
char * str;
int size;
public:
MyString(){
str = new char[2]; //Make sure the allocation is an array
str[0] = 0;//Since it is a string, at least it is an empty string inside, str == NULL cannot be allowed
size = 0;
}
MyString(const char * s) {
//If s == NULL, let it error
size = strlen(s);
str = new char[size+1];
strcpy(str,s);
}
MyString & operator=(const char * s ) {
//If s == NULL, let it error
int len = strlen(s);
if( size < len ) {
delete [] str;
str = new char[len+1];
}
strcpy(str,s);
size = len;
return * this;
}
void duplicate(const MyString & s) {
if( size < s.size ) { //Otherwise, there is no need to reallocate space delete [] str;
str = new char[s.size+1];
}
strcpy(str,s.str);
size = s.size;
}
MyString(const MyString & s):size(0),str(new char[1]) {
duplicate(s);
}
MyString & operator=(const MyString & s) {
if( str == s.str )
return * this;
duplicate(s);
return * this;
}
bool operator==(const MyString & s) const {
return strcmp(str,s.str ) == 0;
}
bool operator<(const MyString & s) const {
return strcmp(str,s.str ) < 0;
}
bool operator>(const MyString & s) const {
return strcmp(str,s.str ) > 0;
}
MyString operator + ( const MyString & s )
{
char * tmp = new char[size + s.size + 2];//Ensure that an array can be allocated
strcpy(tmp,str);
strcat(tmp,s.str);
MyString os(tmp);
delete [] tmp;
return os;
}
MyString & operator += ( const MyString & s) {
char * tmp = new char [size + s.size + 2];
strcpy( tmp, str );
strcat( tmp,s.str);size += s.size;
delete [] str;
str = tmp;
return * this;
}
char & operator[](int i) const {
return str[i];
}
MyString operator()(int start,int len) const {
char * tmp = new char[len + 1];
for( int i = 0;i < len ; ++i)
tmp[i] = str[start+i];
tmp[len] = 0;
MyString s(tmp);
delete [] tmp;
return s;
}
~MyString() { delete [] str; }
friend ostream & operator << ( ostream & o,const MyString & s);
friend MyString operator +( const char * s1,const MyString & s2);
};
ostream & operator << ( ostream & o,const MyString & s)
{
o << s.str ;
return o;
}
MyString operator +( const char * s1,const MyString & s2)
{
MyString tmp(s1);
tmp+= s2;
return tmp;
}
*/ 第十四章习题
1. 以下说法不正确的是(假设在公有派生情况下)
A) 可以将基类对象赋值给派生类对象
B) 可以将派生类对象的地址赋值给基类指针
C) 可以将派生类对象赋值给基类的引用
D) 可以将派生类对象赋值给基类对象
#A
2. Write the output of the following program:
#include <iostream >
using namespace std;
class B {
public:
B(){ cout << "B_Con" << endl; }
~B() { cout << "B_Des" << endl; }
};
class C:public B {
public:
C(){ cout << "C_Con" << endl; }
~C() { cout << "C_Des" << endl; }
};
int main() {
C * pc = new C;
delete pc;
return 0;
}
/*
B_Con
C_Con
C_Des
B_Des
*/
3. Write the output of the following program:
#include <iostream >using namespace std;
class Base {
public:
int val;
Base()
{ cout << "Base Constructor" << endl; }
~Base()
{ cout << "Base Destructor" << endl;}
};
class Base1:virtual public Base { };
class Base2:virtual public Base { };
class Derived:public Base1, public Base2 { };
int main() { Derived d; return 0;}
/*
Base Constructor
Base Destructor
*/
4. Write the MyString class according to the requirements of Question 7 in Chapter 13, but the MyString class must be derived from the string class. Tip 1:
If you replace all "MyString" in the program with "string", then the program in the title will fail to compile except for the last two statements,
There are no problems with other statements, and the output is consistent with the previous results. That is to say, the function extension of the MyString class to the string class
It is only reflected in the last two statements. Tip 2: The string class has a member function string substr(int start,int length);
Can find the substring starting from the start position and having a length of length
/*
class MyString:public string
{
public:
MyString() { }
MyString(const char * s):string(s) { }
MyString(string s):string(s) { }
MyString operator()(int start,int len) const {
return substr(start,len);
}
};
*/
5. Complete the second-stage homework mentioned in the appendix "World of Warcraft Homework".
// by Guo Wei
#include <iostream>#include <cstring>
#include <cstdio>
using namespace std;
//The following things are constants, and more than one class must be used, so it is simpler to declare them as global
#define WARRIOR_NUM 5
#define WEAPON_NUM 3
enum { DRAGON,NINJA,ICEMAN,LION,WOLF };
/*
char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
The Red Command makes warriors in the order of iceman, lion, wolf, ninja, dragon.
The blue team creates warriors in the order of lion, dragon, ninja, iceman, wolf.
*/
class CHeadquarter;
class CDragon;
class CNinja;
class CIceman;
class CLion;
class CWolf;
class CWeapon;
class CWarrior;
class CWeapon
{
public:
you nKindNo;
int nForce;
static int InitialForce[WEAPON_NUM];
static const char * Names[WEAPON_NUM];
};
class CWarrior
{
protected:
CHeadquarter * pHeadquarter;
int nNo; public:
static const char * Names[WARRIOR_NUM];
static int InitialLifeValue [WARRIOR_NUM];
CWarrior(CHeadquarter * p,int nNo_):
pHeadquarter(p),nNo(nNo_) { }
virtual void PrintResult(int nTime,int nKindNo);
virtual void PrintResult(int nTime) = 0;
virtual ~CWarrior() { }
};
class CHeadquarter
{
private:
static const int MAX_WARRIORS = 1000;
int nTotalLifeValue;
bool bStopped;
int nColor;
int nCurMakingSeqIdx;
int anWarriorNum[WARRIOR_NUM];
int nTotalWarriorNum;
CWarrior * pWarriors[MAX_WARRIORS];
public:
friend class CWarrior;
static int MakingSeq[2][WARRIOR_NUM];
void Init(int nColor_, int lv);
~CHeadquarter () ;
int Produce(int nTime);
void GetColor( char * szColor);
int GetTotalLifeValue() { return nTotalLifeValue; }
};
void CWarrior::PrintResult(int nTime,int nKindNo)
{
char szColor[20];pHeadquarter->GetColor(szColor);
printf("%03d %s %s %d born with strength %d,%d %s in %s headquarter\n"
,
nTime, szColor, Names[nKindNo], nNo, InitialLifeValue[nKindNo],
pHeadquarter->anWarriorNum[nKindNo],Names[nKindNo],szColor);
}
class CDragon:public CWarrior
{
private:
CWeapon wp;
double fmorale;
public:
void Countmorale()
{
fmorale = pHeadquarter -> GetTotalLifeValue() /(double)CWarrior::InitialLifeValue [0];
}
CDragon( CHeadquarter * p,int nNo_):
CWarrior(p,nNo_) {
wp.nKindNo = nNo % WEAPON_NUM;
wp.nForce = CWeapon::InitialForce[wp.nKindNo ];
Countmorale();
}
void PrintResult(int nTime)
{
CWarrior::PrintResult(nTime,DRAGON);
printf("It has a %s,and it's morale is %.2f\n",
CWeapon::Names[wp.nKindNo], fmorale);
}
};
class CNinja:public CWarrior
{
private:
CWeapon wps[2];
public:
CNinja( CHeadquarter * p,int nNo_):
CWarrior(p,nNo_) {
wps[0].nKindNo = nNo % WEAPON_NUM;wps[0].nForce = CWeapon::InitialForce[wps[0].nKindNo];
wps[1].nKindNo = ( nNo + 1) % WEAPON_NUM;
wps[1].nForce = CWeapon::InitialForce[wps[1].nKindNo];
}
void PrintResult(int nTime)
{
CWarrior::PrintResult(nTime,NINJA);
printf("It has a %s and a %s\n",
CWeapon::Names[wps[0].nKindNo],
CWeapon::Names[wps[1].nKindNo]);
}
};
class CIceman:public CWarrior
{
private:
CWeapon wp;
public:
CIceman( CHeadquarter * p,int nNo_):
CWarrior(p,nNo_)
{
wp.nKindNo = nNo % WEAPON_NUM;
wp.nForce = CWeapon::InitialForce[ wp.nKindNo ];
}
void PrintResult(int nTime)
{
CWarrior::PrintResult(nTime,ICEMAN);
printf("It has a %s\n",
CWeapon::Names[wp.nKindNo]);
}
};
class CLion:public CWarrior
{
private:
int nLoyalty;
public:
void CountLoyalty(){
nLoyalty = pHeadquarter ->GetTotalLifeValue();
}
CLion(CHeadquarter * p,int nNo_):CWarrior(p,nNo_) {
CountLoyalty();
}
void PrintResult(int nTime)
{
CWarrior::PrintResult(nTime,LION);
CountLoyalty();
printf("It's loyalty is %d\n",nLoyalty);
}
};
class CWolf:public CWarrior
{
public:
CWolf( CHeadquarter * p, int nNo_):
CWarrior(p,nNo_) { }
void PrintResult(int nTime)
{
CWarrior::PrintResult(nTime,WOLF);
}
};
void CHeadquarter::Init(int nColor_, int lv)
{
nColor = nColor_;
nTotalLifeValue = lv;
bStopped = false;
nCurMakingSeqIdx = 0;
nTotalWarriorNum = 0;
for( int i = 0;i < WARRIOR_NUM;i ++ )
anWarriorNum[i] = 0;
}
CHeadquarter::~CHeadquarter () {int i;
for( i = 0;i < nTotalWarriorNum; i ++ )
delete pWarriors[i];
}
int CHeadquarter::Produce(int nTime)
{
int nSearchingTimes = 0;
if( bStopped )
return 0;
while( CWarrior::InitialLifeValue[MakingSeq[nColor][nCurMakingSeqIdx]] > nTotalLifeValue &&
nSearchingTimes < WARRIOR_NUM ) {
nCurMakingSeqIdx = ( nCurMakingSeqIdx + 1 ) % WARRIOR_NUM ;
nSearchingTimes ++;
}
int nKindNo = MakingSeq[nColor][nCurMakingSeqIdx];
if( CWarrior::InitialLifeValue[nKindNo] > nTotalLifeValue ) {
bStopped = true;
if( nColor == 0)
printf("%03d red headquarter stops making warriors\n",nTime);
else
printf("%03d blue headquarter stops making warriors\n",nTime);
return 0;
}
nTotalLifeValue -= CWarrior::InitialLifeValue[nKindNo];
nCurMakingSeqIdx = ( nCurMakingSeqIdx + 1 ) % WARRIOR_NUM ;
int nTmp = anWarriorNum[nKindNo];
anWarriorNum[nKindNo] ++;
switch( nKindNo ) {
case DRAGON:
pWarriors[nTotalWarriorNum] = new CDragon( this,nTotalWarriorNum+1);
break;
case NINJA:
pWarriors[nTotalWarriorNum] = new CNinja( this,nTotalWarriorNum+1);
break;
case ICEMAN:
pWarriors[nTotalWarriorNum] = new CIceman( this,nTotalWarriorNum+1);
break;case LION:
pWarriors[nTotalWarriorNum] = new CLion( this,nTotalWarriorNum+1);
break;
case WOLF:
pWarriors[nTotalWarriorNum] = new CWolf( this,nTotalWarriorNum+1);
break;
}
pWarriors[nTotalWarriorNum]->PrintResult(nTime);
nTotalWarriorNum ++;
return 1;
}
void CHeadquarter::GetColor( char * szColor)
{
if( nColor == 0)
strcpy(szColor,"red");
else
strcpy(szColor,"blue");
}
const char * CWeapon::Names[WEAPON_NUM] = {"sword","bomb","arrow" };
int CWeapon::InitialForce[WEAPON_NUM];
const char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
int CWarrior::InitialLifeValue [WARRIOR_NUM];
int CHeadquarter::MakingSeq[2][WARRIOR_NUM] = { { 2,3,4,1,0 },{3,0,1,2,4} };
int main()
{
int t;
int m;
//freopen("war2.in","r",stdin);
CHeadquarter RedHead,BlueHead;
scanf("%d",&t);
int nCaseNo = 1;
while ( t -- ) {printf("Case:%d\n",nCaseNo++);
scanf("%d",&m);
int i;
for(i = 0;i < WARRIOR_NUM;i ++ )
scanf("%d", & CWarrior::InitialLifeValue[i]);
//
for(i = 0;i < WEAPON_NUM;i ++ )
//
scanf("%d", & CWeapon::InitialForce[i]);
RedHead.Init(0,m);
BlueHead.Init(1,m);
int nTime = 0;
while( true) {
int tmp1 = RedHead.Produce(nTime);
int tmp2 = BlueHead.Produce(nTime);
if( tmp1 == 0 && tmp2 == 0)
break;
nTime ++;
}
}
return 0;
}
Chapter 15 Exercises
1. Which of the following statements is correct
A) The this pointer cannot be used in virtual functions
B) Call the virtual function in the constructor, not dynamic linking
C) Member functions of abstract classes are pure virtual functions
D) Neither the constructor nor the destructor can be a virtual function
#B
2. Write the output of the following program:
#include <iostream>
using namespace std;
class A {
public:
A( ) { }virtual void func()
{ cout << "A::func" << endl; }
~A( ) { }
virtual void fund( )
{ cout << "A::fund" << endl; }
};
class B:public A {
public:
B ( ) { func( ) ; }
void fun( ) { func( ) ; }
~B ( ) { fund( ); }
};
class C : public B {
public :
C( ) { }
void func( )
{cout << "C::func" << endl; }
~C() { fund( ); }
void fund()
{ cout << "C::fund" << endl;}
};
int main()
{
C c; return 0; }
/*
A::func
C::fund
A::fund
*/
3. Write the output of the following program:
#include <iostream>
using namespace std;
class A {
public :
virtual ~A() {cout<<"DestructA" <<endl; }
};
class B: public A {public:
virtual ~B() {cout<<"DestructB" << endl; }
};
class C: public B {
public:
~C() { cout << "DestructC" << endl; }
};
int main() {
A * pa = new C;
delete pa; A a;
return 0;
}
/*
DestructC
DestructB
DestructA
DestructA
*/
4. Write the output of the following program:
#include <iostream >
using namespace std;
class A {
public:
A( ) { }
virtual void func()
{ cout << "A::func" << endl; }
virtual void fund( )
{ cout << "A::fund" << endl; }
void fun()
{ cout << "A::fun" << endl;}
};
class B:public A {
public:
B ( ) { func( ) ; }
void fun( ) { func( ) ; }
};
class C : public B {public :
C( ) { }
void func( )
{cout << "C::func" << endl; }
void fund()
{ cout << "C::fund" << endl;}
};
int main()
{
A * pa = new B();
pa->fun();
B * pb = new C();
pb->fun();
return 0;
}
/*
A::func
A::fun
A::func
C::func
*/
5. The output of the following program is:
A::Fun
C::Do
Please fill in the blank
#include <iostream >
using namespace std;
class A {
private:
int nVal;
public:
void Fun()
{ cout << "A::Fun" << endl; };
void Do()
{ cout << "A::Do" << endl; }
};
class B:public A {public:
virtual void Do()
{ cout << "B::Do" << endl;}
};
class C:public B {
public:
void Do( )
{ cout <<”C::Do”<<endl; }
void Fun()
{ cout << "C::Fun" << endl; }
};
void Call( ___________ ) {
p.Fun(); p.Do();
}
int main() {
C c; Call( c);
return 0;
}
/*
B & p
*/
6. 下面程序的输出结果是:
destructor B
destructor A
请完整写出 class A。 限制条件:不得为 class A 编写构造函数
#include <iostream >
using namespace std;
class A { ……… };
class B:public A {
public:
~B() { cout << "destructor B"
<< endl; }
};
int main() {
A * pa;
pa = new B;
delete pa;return 0;
}
/*
class A {
public:
virtual ~A(){
cout << "destructor A" << endl;
}
};
*/
7. The output of the following program is:
A::Fun
A::Do
A::Fun
C::Do
Please fill in the blank
#include <iostream >
using namespace std;
class A {
private:
int nVal;
public:
void Fun()
{ cout << "A::Fun" << endl; };
virtual void Do()
{ cout << "A::Do" << endl; }
};
class B:public A {
public:
virtual void Do()
{ cout << "B::Do" << endl;}
};
class C:public B {
public:
void Do( )
{ cout <<"C::Do"<<endl; }void Fun()
{ cout << "C::Fun" << endl; }
};
void Call(____________) {
p->Fun(); p->Do();
}
int main() {
Call( new A());
Call( new C());
return 0;
}
/*
A * p
*/
8. Complete the ultimate version of the homework mentioned in the appendix "World of Warcraft Homework".
Chapter 16 Exercises
1. How many stream classes are there in the C++ standard class library? What are the uses? How is the relationship between them?
2. What kind of object is cin? cout is an object of which class?
3. Write a program to read a line of text, and then output this line of text upside down.
Input sample:
These are 100 dogs.
Sample output:
.sgod 001 era esehT
/*
#include <iostream>
#include <cstring>
using namespace std;
char line[3000];
int main()
{
cin.getline(line,2900);
int len = strlen(line);for( int i = len - 1; i >= 0; -- i)
cout.put(line[i]);
return 0;
}
*/
4. 编写程序,输入若干个实数,对于每个实数,先以非科学计数法输出,小数点后面保留 5 位有效数字;
再以科学计数法输出,小数点后面保留 7 位有效数字。输入以 Ctrl+Z 结束。
输入样例:
12.34
123456.892255
输出样例:
12.34000
1.2340000e+001
123456.89226
1.2345689e+005
/*
#include <iostream>
#include <cstring>
#include <iomanip>
using namespace std;
char line[3000];
int main()
{
double f;
while( cin >> f) {
cout << fixed << setprecision(5)<< f << endl;
cout << scientific << setprecision(7) << f << endl;
}
return 0;
}
*/
5. 编写程序,输入若干个整数,对每个整数,先将该整数以十六进制输出,然后再将该整数以 10 个字
符的宽度输出,宽度不足时在左边补 0。输入以 Ctrl+Z 结束。
输入样例:
23
16
输出样例:17
0000000023
10
0000000016
/*
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int n;
while( cin >> n) {
cout << hex << n << endl;
cout << dec << setw(10) << setfill('0') << n << endl;
}
return 0;
}
6. What are the advantages of printf and scanf over cout and cin?
Chapter 18 Exercises
1. The definition of the following function templates is correct:
A) template<class T1, class T2>
T1 fun (T1,T2) { return T1 + T2; }
B) template< class T>
T fun(T a) { return T + a;}
C) tempmlate<class T1,class T2>
T1 fun(T1,T2) { return T1 + T2 ; }
D) template<class T>
T fun(T a,T b) { return a + b ; }
#D
2. The definition of the following class template is correct:
A) template<class T1,class T2>
class A : {
T1 b;int fun( int a ) { return T1+T2; }
};
B) template<class T1,class T2>
class A {
int T2;
T1 fun( T2 a ) { return a + T2; }
};
C) template<class T1,class T2>
class A {
public:
T2 b; T1 a;
A<T1>() { }
T1 fun() { return a; }
};
D) template<class T1,class T2>
class A {
T2 b;
T1 fun( double a ) { b = (T2) a;
return (T1) a; }
};
#D
3. Write the output of the following program:
#include <iostream>
using namespace std;
template <class T>
T Max( T a,T b) {
cout << "TemplateMax" <<endl;
return 0; }
double Max(double a,double b){
cout << "MyMax" << endl;
return 0; }
int main() {
int i=4,j=5;
Max( 1.2,3.4); Max(i,j);
return 0;
}
/*MyMax
TemplateMax
*/
4. Fill in the blanks so that the following program can be compiled and passed, and write the output result:
#include <iostream >
using namespace std;
template <_____________>
class myclass {
T i;
public:
myclass (T a)
{ i = a; }
void show( )
{ cout << i << endl;
}
};
int main() {
myclass<________> obj("This");
obj.show();
return 0;
}
/*
class T
char *
output:
Thiis
*/
5. The output of the following program is:
TomHanks
Please fill in the blank. Note that no constants are allowed.
#include <iostream>
#include <string>
using namespace std;
template <class T>
class myclass {
_________;
int nSize;
public:myclass ( ______________, int n) {
p = new T[n];
for( int i = 0;i < n;++i )
p[i] = a[i];
nSize = n;
}
~myclass( ) {
delete [] p;
}
void Show()
{
for( int i = 0;i < nSize;++i ) {
cout << p[i];
}
}
};
int main() {
char * szName = "TomHanks";
myclass<char >obj(________________);
obj.Show(); return 0;
}
/*
T * p
T * a
szName
output:
TomHanks
*/
6. Programmer Max's programming style is as weird as his personality. Unfortunately, after he was fired, the boss ordered you to take over his job. Max
Before he left, he angrily deleted some code in a class template MyMax he wrote, and you had to make it up. You Only Know MyMax Template
The role of is related to finding the largest element in an array or vector, and the output of the following program is:
5
136
Please fill in the part of the code that Max deleted. This part of the code is all located between "//beginning" and "//end", and there is no byte anywhere else
have.
Mark left the following three conditions in the blank:
1) Do not use any constants other than true and false, and do not assume that the value of true is 1 or any value 2) Do not use any library functions or library templates (including containers and algorithms)
3) Do not use the static keyword
You don't want to behave worse than Max, so whether you keep the code in the MyMax class left by Max or not, you have to abide by these three rules
pieces.
Tip: The third parameter of the copy function template is passed by value
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
template <class T>
class MyMax
{
public:
T * pMax; //Point to the variable used to store the maximum value
bool bFirst;//The mark that will be used when recording the maximum value
MyMax (T * p):bFirst(true),pMax(p) { };
//beginning
//……
//end
};
class A {
public:
int i;
A( int n) :i(n) { };
A() { };
};
bool operator < ( const A & a1, const A & a2)
{
return a1.i < a2.i ; }
ostream & operator<<(ostream &o,const A &a)
{
o << a.i; return o; }
int main() {
A a[5] = {A(1),A(5),A(3),A(4),A(2)};
int b[9] = {1,5,30,40,2,136,80,20,6};
int nMax;
A aMax;
MyMax<A> outputa( & aMax);copy(a,a+5,outputa);
cout << outputa() << endl;
MyMax<int> output( & nMax);
copy(b,b+9,output);
cout << output() << endl;
return 0;
}/*
template <class T>
class MyMax:public iterator<output_iterator_tag,T>
{
public:
T * pMax; //Point to the variable used to store the maximum value
bool bFirst;//The mark that will be used when recording the maximum value
MyMax (T * p):bFirst(true),pMax(p) { };
//beginning
T operator()() {
return * pMax;
}
void operator++() const { }
MyMax<T> & operator *() { return * this; }
MyMax<T> & operator =( const T & val) {
if( bFirst) {
bFirst = false;
* pMax = val;
}
else {
if( * pMax < val )
*pMax = val;
}
}
};
*/
Chapter 19 Exercises
1. Assuming that p1 and p2 are iterators on the list container in STL, which of the following statements does not conform to the syntax A) p1 ++ ; B) p1 --;
C) p1 += 1; D) int n = ( p1 == p2 );
#C
2. When putting an object into a container in STL:
A) What is actually put in is a copy (copy) of the object
B) What is actually put in is a pointer to the object
C) What is actually put in is a reference to the object
D) What is actually put in is the object itself
#A
3. Which of the following statements about function objects is correct:
A) The class to which the function object belongs will overload () as a member function
B) The class to which the function object belongs will overload [] as a member function
C) Function objects do not need to be initialized with constructors when they are generated
D) A function object is actually a function
#A
4. The following correct statement about the set class template in STL is:
A) set is a sequential container
B) The time complexity of finding elements in the set is o(n) (n represents the number of elements in the set)
C) The time to add an element to the set is o(1)
D) The position of an element in a set is related to its value
#D
5. Write the output of the following program:
#include <vector>
#include <iostream>
using namespace std;
class A {
private :
int nId;
public:
A(int n) {
nId = n;
cout << nId << " contructor" << endl; }
~A( )
{cout << nId << " destructor" << endl; }
};
int main() {
vector<A*> vp;
vp.push_back(new A(1));vp.push_back(new A(2));
vp.clear(); A a(4);
return 0;
}
/*
1 builder
2 builder
4 builder
4 destructor
*/
6. Write the output of the following program:
#include <iostream>
#include <map>
using namespace std;
class Gt
{
public:
bool operator() (const int & n1,
const int & n2) const {
return ( n1 % 10 ) > ( n2 % 10);
}
};
int main() {
typedef map<int,double,Gt> mmid;
mmid MyMap;
cout << MyMap.count(15) << endl;
MyMap.insert(mmid::value_type(15,2.7));
MyMap.insert(mmid::value_type(15,99.3));
cout << MyMap.count(15) << endl;
MyMap.insert(mmid::value_type(30,111.11));
MyMap.insert(mmid::value_type(11,22.22));
cout << MyMap[16] << endl;
for( mmid::const_iterator i = MyMap.begin();
i != MyMap.end() ;++i )
cout << "(" << i->first << ","
<< i->second << ")" << ",";
return 0;}
/*
0
1
0
(16,0),(15,2.7),(11,22.22),(30,111.11),
*/
7. The output of the following program is:
Tom,Jack,Mary,John,
Please fill in the blank:
#include <vector>
#include <iostream>
#include <string>
using namespace std;
template <class T>
class MyClass
{
vector<T> array;
public:
MyClass ( T * begin,int n ):array(n)
{ copy( begin, begin + n, array.begin());}
void List() {
________________________;
for(i=array.begin();i!=array.end();++i )
cout << * i << "," ;
}
};
int main() {
string array[4] =
{ "Tom","Jack","Mary","John"};
_________________________;
obj.List();
return 0;
}
/*
typename vector<T>::iterator i
MyClass<string> obj(array,4)或
vector<T>::iterator i
MyClass<string> obj(array,4)
*/
8. The output of the following program is:
A::Print: 1
B::Print: 2
B::Print: 3
Please fill in the blank:
template <class T>
void PrintAll( const T & c ) {
T::const_iterator i;
for( i = c.begin(); i != c.end(); ++i)
_______________________;
};
class A {
protected:
int nVal;
public:
A(int i):nVal(i) { }
virtual void Print()
{ cout << "A::Print: " << nVal << endl; }
};
class B:public A {
public:
B(int i):A(i) { }
void Print()
{ cout << "B::Print: " << nVal << endl; }
};
int main(){
__________________;
v.push_back( new A(1));
v.push_back (new B(2));
v.push_back (new B(3));
PrintAll( v); return 0;
}
/*(*i)->Print();
vector<A*> v;
The second empty list or deque can also be used
*/
9. The output of the following program is:
1 2 6 7 8 9
Please fill in the blank
#include <iostream>
using namespace std;
int main() {
int a[] = {8,7,8,9,6,2,1};
___________________;
for( int i = 0;i < 7;++i)
___________________;
ostream_iterator<int> o(cout," ");
copy( v.begin(),v.end(),o);
return 0;
}
/*
set<int> v
v.insert(a[i])
Or fill in the first blank:
set<int> v(a,a+7)
The second blank can also be left blank
*/
Chapter 20 Exercises
1. What occasions are static_cast, interpret_cast, dynamic_cast, and const_cast used for?
2. Under what circumstances will dynamic_cast throw an exception? What type of exception is thrown? base class pointer with dynamic_cast
How to judge the safety of the conversion to the derived class pointer?
3. The output of the following program is:
2 constructed
step12 destructed
3 constructed
step2
3 destructed
before return
Please fill in the blank:
#include <iostream>
#include <memory>
using namespace std;
class A
{
int v;
public:
A(int n):v(n) { cout << v << " constructed" << endl; }
~A() { cout << v << " destructed" << endl; }
};
int main()
{
A * p = new A ( 2 ) ;
___________________________;
p = NULL;
cout << "step1" << endl;
ptr.reset(NULL);
p = new A(3);
_________________;
p = NULL;
cout << "step2" << endl;
p = ptr._________________;
delete p;
cout << "before return" << endl;
return 0;
}
/*
auto_ptr<A> ptr(p)
ptr.reset(p)
release()
*/ 4. Write the output of the following program:
#include <iostream>
#include <memory>
using namespace std;
class A
{
int v;
public:
A(int n):v(n) { cout << v << " constructed" << endl; }
~A() { cout << v << " destructed"
<< endl; }
};
int main() {
auto_ptr<A> ptr1(new A(3));
auto_ptr<A> ptr2;
ptr2 = ptr1;
ptr1.reset(NULL);
cout << "step1" << endl;
return 0;
}
/*
3 constructed
step1
3 destructed
*/
5. Write the output of the following program:
#include <iostream>
using namespace std;
class A { };
class B:public A {};
int main() {
try {
cout << "before throwing" << endl;
throw B();
cout << "after throwing" << endl;
}
catch( A & ) { cout << "catched 1" << endl; }
catch(B & )
{
cout << "catched 2"
<< endl; }
catch(...)
{
cout << "catched 3" << endl; }
cout << "end" << endl;
return 0;
}
/*
before throwing
catched 1
end
*/
6. Write the output of the following program:
#include <iostream>
#include <exception>
using namespace std;
class A { };
int func1(int m, int n){
try {
if( n == 0 )
throw A();
cout << "in func1" << endl;
return m / n;
}
catch(exception ){
cout << "catched in func1"<< endl;
}
cout << "before end of func1" << endl;
return m/n;
}
int main()
{
try {
func1(5,0);
cout << "in main" << endl;}
catch(A & a) {
cout << "catched in main" << endl;
}
cout << "end of main" << endl;
return 0;
}
/*
catched in main
end of main
*/
7. The output of the following program is:
catched 2
Please fill in the blank:
#include <iostream>
#include <stdexcept>
#include <typeinfo>
#include <exception>
using namespace std;
class A {
public:
virtual void Print()
{ cout << "A::print" << endl;}
};
class B:public A {
public:
virtual void Print()
{ cout << "B::print" << endl;}
};
int main()
{
A a;
try {
B & r = dynamic_cast<B&>(a);
r.Print();
}
catch(A &) { cout << "catched 1" << endl; }
catch( _______________)
{
cout << "catched 2" << endl;}
catch(...)
{
cout << "catched 3"
<< endl;}
return 0;
}
/*
4 possible answers
exception e
exception & e
bad_cast e
bad_case & e
*/

 

Guess you like

Origin blog.csdn.net/shaozheng0503/article/details/129941482