实验四
1、构造一个String类,其数据成员为数组char head[100],构造函数String(char *Head)实现对head的初始化,成员函数int find(char c)查找数组head中字符c第一次出现的位置,成员函数void Print( )实现对head内字符串的输出。
//String.h
#include
using namespace std;
class String {
private:
char head[100];
public:
String(char *Head) {
strcpy(head, Head);
}
int find(char c) {
for (int i = 0; i < strlen(head); i++) {
if (head[i] == c) {
return i;
}
}
return -1;
}
void Print() {
cout << head << endl;
}
};
//main.cpp
int main() {
//1
char str[] = "Hello, world!";
String s(str);
s.Print();
cout << s.find('l') << endl;
system("pause");
return 0;
}
2、声明一个基类BaseClass,从它派生出类DerivedCalss,BaseClass有成员fn1()、fn2(),DerivedClass也有成员函数fn1()、fn2()。在主函数中声明DerivedClass,分别用DerivedClass的对象以及BaseClass和DerivedClass的指针来调用fn1()、fn2(),观察运行结果有什么不同。
//BaseClass.h
#include
using namespace std;
class BaseClass {
public:
void fn1() {
std::cout << "BaseClass fn1()" << std::endl;
}
void fn2() {
std::cout << "BaseClass fn2()" << std::endl;
}
};
class DerivedClass : public BaseClass {
public:
void fn1() {
std::cout << "DerivedClass fn1()" << std::endl;
}
void fn2() {
std::cout << "DerivedClass fn2()" << std::endl;
}
};
//main.cpp
int main() {
DerivedClass obj;
obj.fn1(); // 输?出? "DerivedClass fn1()"
obj.fn2(); // 输?出? "DerivedClass fn2()"
BaseClass* ptr1 = &obj;
ptr1->fn1(); // 输?出? "BaseClass fn1()"
ptr1->fn2(); // 输?出? "BaseClass fn2()"
DerivedClass* ptr2 = &obj;
ptr2->fn1(); // 输?出? "DerivedClass fn1()"
ptr2->fn2(); // 输?出? "DerivedClass fn2()"
system("pause");
return 0;
}
3、 编写一个程序计算出球、圆柱和圆锥的表面积和体积。要求:
(1)定义基类Shape(形状)
(2)派生出球、圆柱、圆锥三个类,包含求各个形状表面积和体积的成员函数getArea()、getVolume( );
(3)在main()中使用基类指针指向每一个派生类对象,并初始化每一个派生类对象。
(4)显示所有图形的总表面积和总体积。
//Shape.h
#include
using namespace std;
const double PI = 3.1415926535; // 定¨义?常£量?PI
class Shape { // 定¨义?基ù类えhape
public:
virtual double getArea() = 0; // 纯?虚é函ˉ数簓,?求ó面?积y
virtual double getVolume() = 0; // 纯?虚é函ˉ数簓,?求ó体?积y
};
class Sphere : public Shape { // 派é生Θ?出?球ò类え?
private:
double radius; // 球ò的?半?径?
public:
Sphere(double r) : radius(r) {} // 构1造ì函ˉ数簓
double getArea() { return 4 * PI * radius * radius; } // 求ó表括?面?积y
double getVolume() { return 4.0 / 3.0 * PI * radius * radius * radius; } // 求ó体?积y
};
class Cylinder : public Shape { // 派é生Θ?出?圆2柱ù类え?
private:
double radius; // 圆2柱ù的?底獭?面?半?径?
double height; // 圆2柱ù的?高?
public:
Cylinder(double r, double h) : radius(r), height(h) {} // 构1造ì函ˉ数簓
double getArea() { return 2 * PI * radius * height + 2 * PI * radius * radius; } // 求ó表括?面?积y
double getVolume() { return PI * radius * radius * height; } // 求ó体?积y
};
class Cone : public Shape { // 派é生Θ?出?圆2锥?类え?
private:
double radius; // 圆2锥?的?底獭?面?半?径?
double height; // 圆2锥?的?高?
public:
Cone(double r, double h) : radius(r), height(h) {} // 构1造ì函ˉ数簓
double getArea() { return PI * radius * (radius + sqrt(radius * radius + height * height)); } // 求ó表括?面?积y
double getVolume() { return 1.0 / 3.0 * PI * radius * radius * height; } // 求ó体?积y
};
//main.cpp
int main() {
Shape* shapes[3]; // 定¨义?基ù类え?指?针?数簓组哩?
shapes[0] = new Sphere(2.0); // 初?始?化ˉ球ò对?象ó
shapes[1] = new Cylinder(2.0, 3.0); // 初?始?化ˉ圆2柱ù对?象ó
shapes[2] = new Cone(2.0, 3.0); // 初?始?化ˉ圆2锥?对?象ó
double a1=0.0;
double a2=0.0;
a1=shapes[0]->getArea ();
a2=shapes[0]->getVolume();
double b1=0.0;
double b2=0.0;
b1=shapes[0]->getArea ();
b2=shapes[0]->getVolume();
double c1=0.0;
double c2=0.0;
c1=shapes[0]->getArea ();
c2=shapes[0]->getVolume();
double d1 = 0.0; // 总哩?表括?面?积y
double d2 = 0.0; // 总哩?体?积y
d1=a1+b1+c1;
d2=a2+b2+c2;
cout << "球ò面?积y: " << a1 << endl;
cout << "球ò体?积y: " << a2 << endl;
cout << "圆2柱ù面?积y: " << a1 << endl;
cout << "圆2柱ù体?积y: " << a2 << endl;
cout << "圆2锥?面?积y: " << a1 << endl;
cout << "圆2锥?体?积y: " << a2 << endl;
cout << "面?积y: " << d1 << endl; // 输?出?总哩?表括?面?积y
cout << "体?积y: " << d2 << endl; // 输?出?总哩?体?积y
system("pause");
return 0;
}
首先定义了一个常量PI,用于计算球、圆柱和圆锥的表面积和体积。
定义了一个基类Shape,其中包含两个纯虚函数getArea()和getVolume(),用于求各个形状的表面积和体积。
派生出三个类Sphere、Cylinder和Cone,分别表示球、圆柱和圆锥。这三个类都继承自基类Shape,并实现了基类中的两个纯虚函数。
在main()函数中,定义了一个基类指针数组shapes,用于指向每一个派生类对象,并初始化每一个派生类对象。
最后输出总表面积和总体积。
4、建立一个基类building,含有保护成员floors、rooms和square,分别用来表示一座楼房的层数、房间数以及它的总面积。建立类building的派生类house,含有私有成员bedrooms,balcony,分别用来表示卧室与阳台的数量。另外建立类building的派生类office,含有私有成员phones和meeting_rooms,分别用来表示电话与会议室的数目。这两个派生类都含有构造函数和show()函数,用于对数据成员进行初始化和显示出这些数据。编写main( )函数显示结果。
//Building.h
#include
using namespace std;
class building {
protected:
int floors; // 层?数簓
int rooms; // 房?间?数簓
double square; // 总哩?面?积y
public:
building(int f, int r, double s) : floors(f), rooms(r), square(s) {}
virtual void show() {
cout << "floors: " << floors << endl;
cout << "rooms: " << rooms << endl;
cout << "square: " << square << endl;
}
};
class house : public building {
private:
int bedrooms; // 卧?室酣?数簓量?
int balcony; // 阳?台?数簓量?
public:
house(int f, int r, double s, int b, int ba) : building(f, r, s), bedrooms(b), balcony(ba) {}
void show() {
building::show();
cout << "bedrooms: " << bedrooms << endl;
cout << "balcony: " << balcony << endl;
}
};
class office : public building {
private:
int phones; // 电?话°数簓量?
int meeting_rooms; // 会á议皑?室酣?数簓量?
public:
office(int f, int r, double s, int p, int m) : building(f, r, s), phones(p), meeting_rooms(m) {}
void show() {
building::show();
cout << "phones: " << phones << endl;
cout << "meeting_rooms: " << meeting_rooms << endl;
}
};
//main.cpp
int main() {
house my_house(2, 4, 100.0, 3, 1);
office my_office(10, 20, 500.0, 50, 5);
cout << "My house:" << endl;
my_house.show();
cout << endl;
cout << "My office:" << endl;
my_office.show();
system("pause");
return 0;
}
在这个代码中,我们建立了一个基类building,它有三个保护成员:floors、rooms和square,分别用来表示一座楼房的层数、房间数以及它的总面积。然后我们建立了两个派生类:house和office。house有两个私有成员:bedrooms和balcony,分别用来表示卧室与阳台的数量;office有两个私有成员:phones和meeting_rooms,分别用来表示电话与会议室的数目。这两个派生类都含有构造函数和show()函数,用于对数据成员进行初始化和显示出这些数据。
在main()函数中,我们创建了一个house对象和一个office对象,并分别调用它们的show()函数来显示出它们的数据成员。
5、定义一个车(vehicle)基类,具有MaxSpeed、Weight成员变量,Run、Stop成员函数,由此派生出自行车(bicycle)类、汽车(motorcar)类。自行车类有高度(height)等属性,汽车类有座位数(SeatNum)等属性。从bicycle和motorcar生出摩托车(motorcycle)类,编写main( )函数显示结果。在继承过程中,注意把vehicle设置为虚基类。如果不把vehicle设置为虚基类,会有什么问题 ?
//Vehicle.h
#include
using namespace std;
class Vehicle {
public:
int MaxSpeed;
int Weight;
virtual void Run() {
cout << "Vehicle is running!" << endl;
}
virtual void Stop() {
cout << "Vehicle has stopped!" << endl;
}
};
class Bicycle : virtual public Vehicle {
public:
int Height;
};
class Motorcar : virtual public Vehicle {
public:
int SeatNum;
};
class Motorcycle : public Bicycle, public Motorcar {
public:
void Run() {
cout << "Motorcycle is running!" << endl;
}
void Stop() {
cout << "Motorcycle has stopped!" << endl;
}
};
//main.cpp
#include
#include "stdlib.h"
#include "String.h"
#include "BaseClass.h"
#include "Shape.h"
#include "Building.h"
#include "Vehicle.h"
using namespace std;
int main() {
Motorcycle m;
m.MaxSpeed = 120;
m.Weight = 300;
m.Height = 1.5;
m.SeatNum = 2;
m.Run();
m.Stop();
system("pause");
return 0;
}
在这个代码中,我们定义了一个基类Vehicle,它有MaxSpeed和Weight两个成员变量,以及Run和Stop两个成员函数。然后我们分别从Vehicle派生出Bicycle和Motorcar类,它们分别有各自的属性。最后我们从Bicycle和Motorcar派生出Motorcycle类,它同时拥有Bicycle和Motorcar的属性。
在这个代码中,我们使用了虚继承,即在Bicycle和Motorcar类的继承中都使用了virtual关键字,这样可以避免在Motorcycle类中出现两份Vehicle的成员变量,从而避免了二义性问题。
如果不使用虚继承,那么在Motorcycle类中会出现两份Vehicle的成员变量,这样就会出现二义性问题,编译器无法确定应该使用哪一个Vehicle成员变量,从而导致编译错误。