实验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);
}

运行结果截图

 task2微调后程序源码

#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);
}

运行结果截图

 归纳总结:

同名覆盖原则:当派生类与基类有同名成员时,若未明确指出,则通过派生类对象使用的是派生类中的同名成员。

二元作用域分辨符:若要通过派生类对象访问基类中被覆盖的同名成员,应使用基类名及作用域分辨符限定。当多个基类存在同名成员时,如果通过派生类对象访问存在二义性,也应使用基类名及作用域分辨符限定。

类型兼容原则:一个公有派生类的对象在使用上可以被当作基类的对象,反之,不可以。虽然类型兼容原则,使得基类指针可以指向派生类对象,但是,通过指针,只能访问从基类继承的公有成员。

task3

Battery.hpp

class Battery {
private:
    int capacity;
public:
    Battery(int a = 70) :capacity(a) {}
    int get_capacity() { return capacity; }
};

Car.hpp

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

class Car {
private:
    string maker, model;
    int year, odometers;
public:
    Car(string a, string b, int c) :maker(a), model(b), year(c) {
        odometers = 0;
    }
    void info();
    void update_odometers(int a) {
        if (a < odometers)
            cout << "error" << endl;
        else
            odometers = a;
    }
};
void Car::info() {
    cout << left << setw(15) << "maker:" << maker << endl;
    cout << left << setw(15) << "model:" << model << endl;
    cout << left << setw(15) << "year:" << year << endl;
    cout << left << setw(15) << "odometers:" << odometers << endl;
}

ElectricCar.hpp

#include<string>
#include <iostream>
#include<iomanip>
#include"Battery.hpp"
#include"Car.hpp"

class ElectricCar :public Car {
private:
    Battery battery;
public:
    ElectricCar(string a, string b, int c, int d = 70) :Car(a, b, c), battery(d) {}
    void info();
};
void ElectricCar::info() {
    Car::info();
    cout << left << setw(15) << "capacity:" << battery.get_capacity() << "-kwh" << endl;
}

task3.cpp

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

int main()
{
    using namespace std;

    // test class of Car
    Car oldcar("Audi", "a4", 2016);
    cout << "--------oldcar's info--------" << endl;
    oldcar.update_odometers(25000);
    oldcar.info();
cout
<< endl; // test class of ElectricCar ElectricCar newcar("Tesla", "model s", 2016); newcar.update_odometers(2500); cout << "\n--------newcar's info--------\n"; newcar.info(); }

运行结果截图

 

 

 

 task4

pets.hpp

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

class MachinePets {
private:
    string nickname;
public:
    MachinePets(const string s) :nickname(s) {}
    virtual string talk() { return ""; }
    string get_nickname() { return nickname; }
};
class PetCats:public MachinePets{
public:
    PetCats(const string s) :MachinePets(s) {}
    string talk() { return "miao wu~"; }
};
class PetDogs:public MachinePets{
public:
    PetDogs(const string s) :MachinePets(s) {}
    string talk() { return "wang wang~"; }
};

task4.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);
}

运行结果截图

 

posted @ 2021-11-27 19:51  Asll321  阅读(30)  评论(2编辑  收藏  举报