实验4 继承

task2:

原:

#include <iostream>
#include <typeinfo>

// definitation of Graph
class Graph
{
public:
    void draw() { std::cout << "Graph::draw() : just as an interface\n"; }
};


// definition of Rectangle, derived from Graph
class Rectangle : public Graph
{
public:
    void draw() { std::cout << "Rectangle::draw(): programs of draw a rectangle\n"; }
};


// definition of Circle, derived from Graph
class Circle : public Graph
{
public:
    void draw() { std::cout << "Circle::draw(): programs of draw a circle\n"; }
};


// definitaion of fun(): as a call interface
void fun(Graph *ptr)
{
    std::cout << "pointer type: " << typeid(ptr).name() << "\n";
    std::cout << "RTTI type: " << typeid(*ptr).name() << "\n";
    ptr -> draw();
}

// test 
int main()
{
    Graph g1;
    Rectangle r1;
    Circle c1;

    // call by object name
    g1.draw();
    r1.draw();
    c1.draw();

    std::cout << "\n";

    // call by object name, and using the scope resolution operator::
    r1.Graph::draw();
    c1.Graph::draw();

    std::cout << "\n";

    // call by pointer to Base class
    fun(&g1);
    fun(&r1);
    fun(&c1);
}

实验4 继承

 

归纳总结:

同名覆盖原则:
当派生类的函数名或者成员名与基类的函数名或成员名发生重复(哪怕它们形参列表不同),将自动隐藏其父类的同名函数或对象,要使用其父类对应的函数或成员需要用父类作用域来进行说明。
二元作用域分辨符:
即“::”,是双目运算符,常用于:类名::成员,表示该成员是在该类下的成员。
类型兼容原则:
1.子类对象可以当作父类对象使用
2.子类对象可以直接赋值给父类对象
3.子类对象可以直接初始化父类对象
4.父类指针可以直接指向子类对象
5.父类引用可以直接引用子类对象
在替代之后,派生类对象就可以作为基类的对象使用,但是只能使用从基类继承的成员。

改:

#include <iostream>
#include <typeinfo>

// definitation of Graph
class Graph
{
public:
    virtual void draw() { std::cout << "Graph::draw() : just as an interface\n"; }
};


// definition of Rectangle, derived from Graph
class Rectangle : public Graph
{
public:
    void draw() { std::cout << "Rectangle::draw(): programs of draw a rectangle\n"; }
};


// definition of Circle, derived from Graph
class Circle : public Graph
{
public:
    void draw() { std::cout << "Circle::draw(): programs of draw a circle\n"; }
};


// definitaion of fun(): as a call interface
void fun(Graph *ptr)
{
    std::cout << "pointer type: " << typeid(ptr).name() << "\n";
    std::cout << "RTTI type: " << typeid(*ptr).name() << "\n";
    ptr -> draw();
}

// test 
int main()
{
    Graph g1;
    Rectangle r1;
    Circle c1;

    // call by object name
    g1.draw();
    r1.draw();
    c1.draw();

    std::cout << "\n";

    // call by object name, and using the scope resolution operator::
    r1.Graph::draw();
    c1.Graph::draw();

    std::cout << "\n";

    // call by pointer to Base class
    fun(&g1);
    fun(&r1);
    fun(&c1);
}

实验4 继承

 

task3:

Battery.hpp:

#include<iostream>
using namespace std;

class Battery
{
public:
    int capacity;
    
    Battery(int n_capacity=70):capacity(n_capacity){
    }
    
    int get_capacity()
    {
        return capacity;
    }
    
    ~Battery()=default;    
};

 

Car.hpp:

#include<iostream>
#include<string>
#include<iomanip>
using namespace std;

class Car
{
public:
    string maker;
    string model;
    int year;
    int odometers;
    
    Car(string n_maker,string n_model,int n_year,int n_odometers=0):maker(n_maker),model(n_model),year(n_year),odometers(n_odometers){
    }
    
    void info()
    {
        cout<<setw(16)<<setiosflags(ios::left)<<"maker:"<<maker<<endl;
        cout<<setw(16)<<setiosflags(ios::left)<<"model:"<<model<<endl;
        cout<<setw(16)<<setiosflags(ios::left)<<"year:"<<year<<endl;
        cout<<setw(16)<<setiosflags(ios::left)<<"odometers:"<<odometers<<endl;
    }
    
    void update_odometers(int n_odometers)
    {
        if(n_odometers<odometers)
            cout<<"更新值有误"<<endl;
        else
            odometers=n_odometers;
    }
    
    ~Car()=default;
};

 

ElectricCar.hpp:

#include<iostream>
#include<string>
#include"Car.hpp"
#include"Battery.hpp"
using namespace std;

class ElectricCar:public Car
{
public:
    ElectricCar(string n_maker,string n_model,int n_year,int n_odometers=0,int n_capacity=70):
    Car(n_maker,n_model,n_year,n_odometers){
        Battery battery(n_capacity);
    }
    
    void info()
    {
        cout<<setw(16)<<setiosflags(ios::left)<<"maker:"<<maker<<endl;
        cout<<setw(16)<<setiosflags(ios::left)<<"model:"<<model<<endl;
        cout<<setw(16)<<setiosflags(ios::left)<<"year:"<<year<<endl;
        cout<<setw(16)<<setiosflags(ios::left)<<"odometers:"<<odometers<<endl;
        cout<<setw(16)<<setiosflags(ios::left)<<"capacity:"<<battery.capacity<<"-kWh"<<endl;
    }
    
    ~ElectricCar()=default;
    private:
        Battery battery; 
};

 

cpp:

#include <iostream>
#include "electricCar.hpp"

int main()
{
    using namespace std;

    // test class of Car
    Car oldcar("ATO", "z14", 2030);
    cout << "--------oldcar's info--------" << endl;
    oldcar.update_odometers(300000);
    oldcar.info();

    cout << endl;

    // test class of ElectricCar
    ElectricCar newcar("Kesla", "model max", 3060);
    newcar.update_odometers(4500);
    cout << "\n--------newcar's info--------\n";
    newcar.info();
}

实验4 继承

 

task4:

hpp:

#include<iostream>
#include<string>
using namespace std;

class MachinePets
{
public:
    string     nickname;
    
    MachinePets(const string s):nickname(s){
    }
    
    string get_nickname() const
    {
        return nickname;
    }
    
    virtual string talk(){
    }
    
    ~MachinePets()=default;
};

class PetCats:public MachinePets
{
public:
    PetCats(const string s):MachinePets(s){
    }
    
    string talk()
    {
        return "miao wu~";
    }
    
    ~PetCats()=default;
};

class PetDogs:public MachinePets
{
public:
    PetDogs(const string s):MachinePets(s){
    }
    
    string talk()
    {
        return "wang wang~";
    }
    
    ~PetDogs()=default;
};

 

cpp:

#include <iostream>
#include "pets.hpp"

void play(MachinePets *ptr)
{
    std::cout << ptr->get_nickname() << " says " << ptr->talk() << std::endl;
}

int main()
{
    PetCats cat("miku");
    PetDogs dog("da huang");

    play(&cat);
    play(&dog);
}

实验4 继承

 

上一篇:Ruby Regexp


下一篇:elasticsearch的基本用法