实验任务1:
(1)map 将学号转换为小写字母:
exc1.cpp
1 #include<iostream> 2 #include<string> 3 #include<map> 4 5 int main(){ 6 using namespace std; 7 8 map<char,string> studentNum{{'0',"a"},{'1',"b"},{'2',"c"},{'3',"d"},{'4',"e"},{'5',"f"},{'6',"g"},{'7',"h"},{'8',"i"},{'9',"j"}}; 9 string num; 10 while(getline(cin,num)){ 11 for(auto i=0;i<num.length();i++){ 12 for(auto j='0';j<='9';j++) 13 if(num[i]==j) 14 cout<<studentNum[j]; 15 } 16 cout<<endl; 17 } 18 }
测试图:
(2)map 进制转换
源代码:
exc2.cpp
1 #include<iostream> 2 #include<string> 3 #include<map> 4 using namespace std; 5 map<int,string> dex_hex_dict{{10,"A"},{11,"B"},{12,"C"},{13,"D"},{14,"E"},{15,"F"}}; 6 void d2n(int m,int n); 7 void d2n(int m); 8 9 int main(){ 10 cout<<42<<endl; 11 d2n(42); 12 d2n(42,2); 13 d2n(42,8); 14 d2n(42,16); 15 cout<<endl; 16 cout<<65<<endl; 17 d2n(65); 18 d2n(65,2); 19 d2n(65,8); 20 d2n(65,16); 21 } 22 void d2n(int m,int n){ 23 int t[100],i; 24 i=0; 25 while(m){ 26 t[i++]=m%n; 27 m/=n; 28 } 29 if(n==2) cout<<"Dec:\t\t\t"; 30 if(n==8) cout<<"Oct:\t\t\t"; 31 if(n==16) cout<<"Hex:\t\t\t"; 32 33 for(auto j=i-1;j>=0;j--) 34 if(t[j]>=0&&t[j]<=9) 35 cout<<t[j]; 36 else{ 37 for(auto k=10;k<=15;k++) 38 if(t[j]==k) 39 cout<<dex_hex_dict[k]; 40 } 41 cout<<endl; 42 } 43 void d2n(int m){ 44 cout<<"default:"; 45 d2n(m,2); 46 }
测试图:
实验任务2:
task2.cpp:
(1)无virtual时
1 #include<iostream> 2 #include<typeinfo>//typeinfo可以用于获得运行时类型信息 3 4 // definition of Graph 5 class Graph{ 6 public: 7 void draw(){ 8 std::cout<<"Graph::draw():just as an interface\n"; 9 } 10 }; 11 12 //definition of Rectangle,derived from Graph 13 class Rectangle:public Graph{ 14 public: 15 void draw(){ 16 std::cout<<"Rectangle::draw():programs of draw a rectangle\n"; 17 } 18 }; 19 20 //definition of Circle,derived from Graph 21 class Circle:public Graph{ 22 public: 23 void draw(){ 24 std::cout<<"Circle::draw():programs of draw a circle\n"; 25 } 26 }; 27 28 //definition of fun():as a call interface RTTI: Runtime Type Info 29 void fun(Graph *ptr){ 30 std::cout<<"pointer type:"<<typeid(ptr).name()<<"\n"; 31 std::cout<<"RTTI type:"<<typeid(*ptr).name()<<"\n"; 32 ptr->draw(); 33 } 34 35 //test 36 int main(){ 37 Graph g1; 38 Rectangle r1; 39 Circle c1; 40 41 //call by object name 42 g1.draw(); 43 r1.draw(); 44 c1.draw(); 45 46 std::cout<<"\n"; 47 48 //call by object name,and using the scope resolution operator:: 49 r1.Graph::draw(); 50 c1.Graph::draw(); 51 52 std::cout<<"\n"; 53 54 //call by pointer to Base class 55 fun(&g1); 56 fun(&r1); 57 fun(&c1); 58 }
测试图:
(2)有virtual时
1 #include<iostream> 2 #include<typeinfo>//typeinfo可以用于获得运行时类型信息 3 4 // definition of Graph 5 class Graph{ 6 public: 7 void virtual draw(){ 8 std::cout<<"Graph::draw():just as an interface\n"; 9 } 10 }; 11 12 //definition of Rectangle,derived from Graph 13 class Rectangle:public Graph{ 14 public: 15 void draw(){ 16 std::cout<<"Rectangle::draw():programs of draw a rectangle\n"; 17 } 18 }; 19 20 //definition of Circle,derived from Graph 21 class Circle:public Graph{ 22 public: 23 void draw(){ 24 std::cout<<"Circle::draw():programs of draw a circle\n"; 25 } 26 }; 27 28 //definition of fun():as a call interface RTTI: Runtime Type Info 29 void fun(Graph *ptr){ 30 std::cout<<"pointer type:"<<typeid(ptr).name()<<"\n"; 31 std::cout<<"RTTI type:"<<typeid(*ptr).name()<<"\n"; 32 ptr->draw(); 33 } 34 35 //test 36 int main(){ 37 Graph g1; 38 Rectangle r1; 39 Circle c1; 40 41 //call by object name 42 g1.draw(); 43 r1.draw(); 44 c1.draw(); 45 46 std::cout<<"\n"; 47 48 //call by object name,and using the scope resolution operator:: 49 r1.Graph::draw(); 50 c1.Graph::draw(); 51 52 std::cout<<"\n"; 53 54 //call by pointer to Base class 55 fun(&g1); 56 fun(&r1); 57 fun(&c1); 58 }
测试图:
(3)归纳:
(i) 同名覆盖原则:派生类和基类的成员名相同的时,若未强行指名则调用时采用派生类的成员;
(ii)二元作用域分辨符: 类名称::成员名,避免不同的类中含有相同的成员名而进行区分;
(iii)类型兼容原则:在需要基类对象的任何地方都可以使用公有派生类的对象来替代:
(a)派生类对象可以隐含转化为基类对象,b1=d1;
(b)派生类的对象可以初始化基类的引用,B &rb=d1;
(c)派生类的指针可以隐含转化为基类的指针,pb1=&d1;
实验任务3:
1 #ifndef BATTERY_HPP 2 #define BATTERY_HPP 3 4 #include<iostream> 5 6 class Battery{ 7 public: 8 Battery(int capacity0=70):capacity{capacity0}{} 9 int get_capacity()const{return capacity;} 10 private: 11 int capacity; 12 }; 13 14 #endif
1 #ifndef CAR_HPP 2 #define CAR_HPP 3 4 #include<iostream> 5 #include<string> 6 7 using namespace std; 8 class Car{ 9 public: 10 Car(string maker0,string model0,int year0,double odometers); 11 void info()const; 12 void update_odometers(double new_odometers); 13 string get_maker()const{return maker;} 14 private: 15 string maker, model; 16 int year; 17 double odometers; 18 }; 19 Car::Car(string maker0="***",string model0="***",int year0=0,double odometers0=0):maker{maker0},model{model0},year{year0},odometers{odometers0}{} 20 void Car::info()const{ 21 cout<<"maker:\t\t\t"<<maker<<"\n" 22 <<"model:\t\t\t"<<model<<"\n" 23 <<"year:\t\t\t"<<year<<"\n" 24 <<"odometers:\t\t"<<odometers<<"\n"; 25 } 26 void Car::update_odometers(double new_odometers){ 27 if(new_odometers<odometers) 28 std::cout<<"WARNING! THE NEW INFO IS ERROR!\n"; 29 else 30 odometers=new_odometers; 31 } 32 33 #endif
1 #ifndef ELECTRICCAR_HPP 2 #define ELECTRICCAR_HPP 3 4 #include"car.hpp" 5 #include"battery.hpp" 6 7 #include<iostream> 8 #include<string> 9 using namespace std; 10 class ElectricCar:public Car{ 11 public: 12 ElectricCar(string maker0,string model0,int year0,double odometers0=0,int capacity0=70); 13 void info()const; 14 private: 15 Battery battery; 16 }; 17 ElectricCar::ElectricCar(string maker0,string model0,int year0,double odometers0,int capacity0):Car(maker0,model0,year0,odometers0),battery(capacity0){} 18 void ElectricCar::info()const{ 19 Car::info(); 20 cout<<"capacity:\t\t"<<battery.get_capacity()<<endl; 21 } 22 #endif
1 #include"electricCar.hpp" 2 #include<iostream> 3 int main(){ 4 using namespace std; 5 6 //test class of Car 7 Car oldcar("Audi","a4",2016); 8 cout<<"--------oldcar's info--------"<<endl; 9 oldcar.update_odometers(25000); 10 oldcar.info(); 11 12 cout<<endl; 13 14 //test class of ElectricCar 15 ElectricCar newcar("Porsche","GSP",2020); 16 newcar.update_odometers(5300); 17 cout<<"\n--------newcar's info--------\n"; 18 newcar.info(); 19 }
测试图:
实验任务4:
1 #ifndef PETS_HPP 2 #define PETS_HPP 3 4 #include<iostream> 5 #include<string> 6 using namespace std; 7 8 class MachinePets{ 9 public: 10 MachinePets(const string s):nickname(s){} 11 virtual string talk(){return "";} 12 string get_nickname()const{ 13 return nickname; 14 } 15 private: 16 string nickname; 17 }; 18 19 class PetCats:public MachinePets{ 20 public: 21 PetCats(const string s):MachinePets(s){} 22 string talk(){ 23 return "miao wu ~"; 24 } 25 }; 26 class PetDogs:public MachinePets{ 27 public: 28 PetDogs(const string s):MachinePets(s){} 29 string talk(){ 30 return "wang wang ~"; 31 } 32 }; 33 34 #endif
1 #include"pets.hpp" 2 #include<iostream> 3 4 void play(MachinePets *ptr){ 5 std::cout<<ptr->get_nickname()<<" says "<<ptr->talk()<<std::endl; 6 } 7 8 int main(){ 9 PetCats cat("miku"); 10 PetDogs dog("da huang"); 11 12 play(&cat); 13 play(&dog); 14 return 0; 15 }
测试图:
实验任务5:
总结:
1.通过本次实验,我更了解了map的用法;
2.关于虚基类的使用,virtual解决了共基类导致的多个副本造成的内存浪费以及数据不一致的问题;
3.深刻了解有关基类和派生类的用法以及关系。