C++习题与解析-继承和派生
给自己一点时间接受自己,爱自己,趁着下午茶的时间来学习图老师推荐的C++习题与解析-继承和派生,过去的都会过去,迎接崭新的开始,释放更美好的自己。
6.1 分析以下程序的执行结果
#includeiostream.h
class base
{
public:
base(){cout"constrUCting base class"endl;}
~base(){cout"destructing base class"endl; }
};
class subs:public base
{
public:
subs(){cout"constructing sub class"endl;}
~subs(){cout"destructing sub class"endl;}
};
void main()
{
subs s;
}
解:
本题说明单继续情况下构造函数和析构函数的调用顺序。这里base为基类,subs为派生类。
所以输出为:
constructing base class
constructing sub class
destructing sub class
destrcuting base class
注重:在单继续情况下,首先调用基类的构造函数 ,随后调用派生类的构造函数,析构函数的调用顺序则正好相反。
---------------------------------------------------
6.2 分析以下程序的执行结果:
#includeiostream.h
class base
{
int n;
public:
base(int a)
{
cout"constructing base class"endl;
n=a;
cout"n="nendl;
}
~base(){cout"destructing base class"endl;}
};
class subs:public base
{
base bobj;
int m;
public:
subs(int a,int b,int c):base(a),bobj(c)
{
cout"constructing sub cass"endl;
m=b;
cout"m="mendl;
}
~subs(){cout"destructing sub class"endl;}
};
void main()
{
subs s(1,2,3);
}
解:
本题说明 派生类中含有对象成员情况下构造函数和析构函数的调用顺序。这里base为基类,subs为派生类,subs类的构造函数中含有对象成员。
所以输出为:
constrcuting base class
n=1
constructing base class
n=3
constructing sub class
m=2
destructing sub class
destructing base class
destructing base class
注重:当派生类中含有对象成员时,构造函数的调用顺序如下:
1)基类的构造函数
2)对象成员的构造函数
3)派生类的构造函数
析构函数的调用顺序与之相反
-------------------------------------------------
6.3 分析以下程序的执行结果
#includeiostream.h
class A
{
public:
int n;
};
class B:public A{};
class C:public A{};
class D:public B,public C
{
int getn(){return B::n;}
};
void main()
{
D d;
d.B::n=10;
d.C::n=20;
coutd.B::n","d.C::nendl;
}
解:
D类是从类和类派生的而类和类又都是从类派生的,但各有自己的副本。所以对于对象d,d.B::n与d.C::n是两个不同的数据成员它们互无联系。
所以输出为:
10,20 -------------------------------------------- 6.4 分析以下程序的执行结果
#includeiostream.h
class A
{
public:
int n;
};
class B:virtual public A{};
class C:virtual public A{};
class D:public B,public C
{
int getn(){return B::n;}
};
void main()
{
D d;
d.B::n=10;
d.C::n=20;
coutd.B::n","d.C::nendl;
}
解:
D类是从类和类派生的而类和类又都是从类派生,但这是虚继续关系即是虚基类因此和共用一个的副本所以对于对象d,d.B::n与d.C::n是一个成员。
所以输出为:
20,20
--------------------------------------- 6.5 假设图书馆的图书包含书名、编号作者属性读者饮包含姓名和借书证属性每位读者最多可借5本书,编写程序列出某读者的借书情况。
解:
设计一个类,从它派生出胃病书类book和读者类reader,在reader类中有一个rentbook()成员函数用于借阅图书。
程序代码如下:
本程序的执行结果如下:
#includeiostream.h
#includestring.h
class object
{
char name[20];
int no;
public:
object(){}
object(char na[],int n)
{
strcpy(name,na);no=n;
}
void show()
{
coutname"("no")";
}
};
class book:public object
{
char author[10];
public:
book(){}
book(char na[],int n,char auth[]):object(na,n)
{
strcpy(author,auth);
}
void showbook()
{
show();
cout"作者:"author;
}
};
class reader:public object
{
book rent[5];
int top;
public:
reader(char na[],int n):object(na,n){top=0;}
void rentbook(book &b)
{
rent[top]=b;
top++;
}
void showreader()
{
cout"读者:";show();
coutendl"所借图书:"endl;
for(int i=0;itop;i++)
{
cout" "i+1":"; // 5个空格
rent[i].show();
coutendl;
}
}
};
void main()
{
book b1("C语言",100,"谭浩强"),b2("数据结构",110,"严蔚敏");
reader r1("王华",1234);
r1.rentbook(b1);
r1.rentbook(b2);
r1.showreader();
}
读者王华(1234)
所借图书:
1:C语言(100)
2:数据结构(110)6.6 编写一个程序设计一个汽车类vehicle,包含的数据成员有车轮个数wheels和车重weight。小车类car是它的私有派生类其中包含载人数passenger_load。卡车类truck是vehicle的私有派生类其中包含载人数passenger_load和载重量payload,每个类都有相关数据的输出方法。
解:
vehicle类是基类由它派生出car类和truck类将公共的属性和方法放在vehicle类中。
本题程序如下:
本程序的执行结果如下:
#includeiostream.h
class vehicle // 定义汽车类
{
protected:
int wheels; // 车轮数
float weight; // 重量
public:
vehicle(int wheels,float weight);
int get_wheels();
float get_weight();
float wheel_load();
void show();
};
class car:public vehicle // 定义小车类
{
int passenger_load; // 载人数
public:
car(int wheels,float weight,int passengers=4);
int get_passengers();
void show();
};
class truck:public vehicle // 定义卡车类
{
int passenger_load; // 载人数
float payload; // 载重量
public:
truck(int wheels,float weight,int passengers=2,float max_load=24000.00);
int get_passengers();
float efficiency();
void show();
};
vehicle::vehicle(int wheels,float weight)
{
vehicle::wheels=wheels;
vehicle::weight=weight;
}
int vehicle::get_wheels()
{
return wheels;
}
float vehicle::get_weight()
{
return weight/wheels;
}
void vehicle::show()
{
cout "车轮:" wheels "个" endl;
cout "重量:" weight "公斤" endl;
}
car::car(int wheels, float weight,
int passengers) :vehicle (wheels, weight)
{
passenger_load=passengers;
}
int car::get_passengers ()
{
return passenger_load;
}
void car::show()
{
cout " 车型:小车" endl;
vehicle::show();
cout "载人:" passenger_load "人" endl;
cout endl;
}
truck:: truck(int wheels, float weight,int passengers, float max_load):vehicle(wheels,weight)
{
passenger_load=passengers;
payload=max_load;
}
int truck::get_passengers()
{
return passenger_load;
}
float truck::efficiency()
{
return payload/(payload+weight);
}
void truck::show()
{
cout "车型:卡车" endl;
vehicle:: show ();
cout "载人:" passenger_load "人" endl;
cout "效率:" efficiency() endl;
cout endl;
}
void main ()
{
car car1(4,2000,5);
truck tru1(10,8000,3,340000);
cout "输出结果" endl;
car1. show ();
tru1. show ();
}
输出结果
车型:小车
车轮:4个
重量:2000公斤
载人:5人
车型:卡车
车轮:10个
重量:8000公斤
载人:3人
效率:0.977012
--------------------------------------------------------
6.7 设计一个圆类circle和一个桌子类table,另设计一个圆桌类roundtable,它是从前两个类派生的,要求输出一个圆桌的高度、面积和颜色等数据。
解:
circle类包含私有数据成员radius和求圆面积的成员函数getarea();table类包含私有数据成员height和返回高度的成员函数getheight()。roundtable类继续所有上述类的数据成员和成员函数,添加了私有数据成员color和相应的成员函数。本题程序如下:
#includeiostream.h
#includestring.h
class circle
{
double radius;
public:
circle(double r) { radius=r; }
double getarea() { return radius*radius*3.14; }
};
class table
{
double height;
public:
table(double h) { height=h; }
double getheight() { return height; }
};
class roundtable : public table,public circle
{
char *color;
public:
roundtable(double h, double r, char c[]) : circle (r) , table (h)
{
color=new char[strlen(c)+1];
strcpy (color, c);
}
char *getcolor() { return color; }
};
void main()
{
roundtable rt(0.8,1.2,"黑色");
cout "圆桌属性数据:" endl;
cout "高度:" rt.getheight() "米" endl;
cout "面积:" rt.getarea() "平方米" endl;
cout "颜色:" rt.getcolor() endl;
}
本程序的执行结果如下:
圆桌属性数据:
高度:0.8米
面积:4.5216平方米
颜色:黑色
-------------------------------------------------------
6.8 设计一个虚基类base,包含姓名和年龄私有数据成员以及相关的成员函数,由它派生出领导类leader,包含职务和部门私有数据成员以及相关的成员函数。再由base派 生出工程师类engineer,包含职称和专业私有数据成员以及相关的成员函数。然后由1eda和engineer类派生出主任工程师类chairman。采用一些数据进行测试。
解:
由于chairman类从leader类和engineer类派生,而leader类和engineer类都是从base类派生的,所以为了使base只存一个副本,必须采用虚拟派生的方法。
本题程序如下:
#includeiostream.h
#includestring.h
class base // 基类
{
char* name;// 姓名
int age; // 年龄
public:
base(){}
void setname(char na[])
{
name=new char[strlen(na)+1];
strcpy(name,na);
}
void setage(int a)
{
age=a;
}
char* getname() { return name; }
int getage() { return age; }
};
class leader:virtual public base // 领导类
{
char *job;//职务
char *dep;//部门
public:
leader() { }
void setjob(char jb[])
{
job=new char[strlen(jb)+1];
strcpy (job, jb);
}
void setdep(char dp[])
{
dep=new char [strlen (dp) +1] ;
strcpy (dep, dp);
}
char *getjob() { return job; }
char *getdep() { return dep; }
};
class engineer:virtual public base // 工程师类
{
char *major; // 专业
char *prof; // 职称
public:
engineer () { }
void setmajor(char maj [])
{
major=new char[strlen(maj)+1];
strcpy (major,maj);
}
void setprof(char pf[])
{
prof=new char[strlen(pf)+1];
strcpy (prof, pf);
}
char*getmajor() {return major; }
char*getprof() {return prof; }
} ;
class chairman:public leader,public engineer // 主任工程师类
{ } ;
void main()
{
chairman c;
c.setname("李明");
c.setage(42);
c.setjob("处长");
c.setdep("设计处");
c.setmajor("电站锅炉设计");
c.setprof("高级工程师");
cout "输出结果:"endl;
cout " " c.getname() ",年龄" c.getage()"岁,担任" c.getdep() c.getjob() ","endl;
cout " " c.getprof() ",从事" c.getmajor() "专业" "。 " endl;
}
本程序的执行结果如下:
输出结果:
李明,年龄42岁,担任设计处处长,
高级工程师,从事电站锅炉设计专业。 三层交换技术交换机与路由器密码恢复交换机的选购 路由器设置专题路由故障处理手册数字化校园网解决方案
题 1. 分析以下程序的执行结果:
#includeiostream.h
class base
{
int n;
public:
base(){};
base (int a)
{
cout "constructing base class" endl;
n=a;
cout "n=" n endl;
}
~base() { cout "destructing base class" endl; }
};
class subs : public base
{
int m;
public:
subs(int a, int b) : base(a)
{
cout "constructing sub class" endl;
m=b;
cout "m=" m endl;
}
subs() { cout "destructing sub class" endl; }
};
void main ()
{
subs s(1,2);
}
解:
这里base 是基类,subs为派生类,subs类的构造函数中含有调用基本类的构造函数。
所以输出为:
constructing base class
n=1
constructing sub class
n=2
destructing base class
destructing sub class
-----------------------------------------------------
题 2.分析以下程序的执行结果:
#include iostream.h
class Sample
{
protected:
int x;
public:
Sample() { x=0; }
Sample(int val) { x=val; }
void operator++() { x++; }
};
class Derived:public Sample
{
int y;
public:
Derived():Sample(){ y=0; }
Derived(int val1,int val2):Sample(val1){ y=val2; }
void operator--(){ x--;y--;}
void disp()
{
cout"x=" x " y=" y endl; f
}
};
void main ()
{
Derived d(3,5);
d.disp();
d++;
d.disp ();
d--;
d--;
d.disp();
}
解:
所有运算都是对x而言的。
所以输出为:
x=3, y=5
x=4,y=5
x=2,y=5
--------------------------------------------------------------
题 3 分析以下程序的执行结果:
#include iostream.h
class A
{
int a;
public:
A(int i) { a=i;cout "constructing class A" endl; }
void print() { cout a endl; }
~A() { cout "destructing class A" endl; }
};
class Bi:public A
{
int bl;
public:
Bl(int i,int j):A(i)
{
bl=j;cout "constructing class BI" endl;
void print()
{
A::print ();
cout bl endl;
}
~BI(){ cout "destructing class BI" endl; }
};
class B2:public A
{
int b2;
public:
B2(int i,int j):A(i);
{
b2=j;cout "constructing class B2" endl;
}
void print()
{
A::print ();
cout b2 endl;
}
~B2() { cout "destructing class B2" endl; }
};
class C:public B1,public B2
{
int c;
public:
C(int i,int j,int k, int 1,int m) :Bl(i,j),B2(k,1),c(m)
{
cout "constructing class C" endl;
}
void print()
{
Bl::print();
B2::print();
cout c endl;
}
~C( ){ cout "destructing class C" endl; }
};
void main()
{
C c1(1,2,3,4,5);
cl.print();
}
解:
C类是从B1类和B2类派生的,而B1和B2类又都是从A类派生,但各有自己的副本,所有这些成员函数均有print()成员函数。所以,在C的成员函数实现中,调用print()时,要加上类作用域运算符“::”。
所以输出为:
constructing class A
constructing class B1
constructing class A
constructing class B2
constructing class C
1
2
3
4
5
destructing class C
destructing class B2
destructing class A
destructing class B1
destructing class A
-------------------------------------------------------
题 4 分析以下程序执行结果:
#include iostream.h
class A
{
public:
A(char *s) { cout s endl; }
~A() {}
};
class B:public A
{
public:
B(char *sl,char *s2) :A(sl)
{
cout s2 endl;
}
};
class C:public A
{
public:
C(char *sl,char *s2) :A(sl)
{
cout s2 endl;
}
};
class D:public B,public C
{
public:
D(char *sl,char *s2,char *s3,char *s4) :B(sl,s2),C(sl,s3)
{
cout s4 endl;
}
void main ()
{
D d("class A","class B","class C","class D");
}
解:
D类是从B和C类派生的,而B和C类又都是从A类派生,但各有自己的副本。
所以输出为:
class A
class B
class A
class C
class D