电商专业学习嵌入式软件开发第五十九天

  • C++第五天

今天继续讲多继承,主要讲了继承的构造顺序和菱形继承以及虚函数和动态多态,还讲了异质链表。今天讲的派生类和基类的赋值着实是把我绕晕了,尤其是到了后面又出现了指针,直接就是晕着过去的。老师还让我们写一下异质链表当作作业,结果还是写不出来。今天终于将项目一做出来了,虽然有些瑕疵(比如在输入的时候不小心会段错误),但是该有的功能都有了,可以运行了,后期慢慢修改瑕疵就好了。

c++中空类大小是1
继承的构造顺序(先基类后本身)
用哪个生成对象,哪个就是最派生类
构造顺序:先是被虚继承的基类,然后是正常继承的基类,最后是本身
函数模板是静态多态
动态多态:直到运行到的时候才知道用哪个动作
cpu最小执行单元是线程

#include <iostream>
#include <string>
using namespace std;
//菱形问题使用虚继承来解决
class People
{
public:
    People(){cout << "People()\n";}
    People(string id, string name, string born, string addr)
    : m_strId(id), m_strBorn(born)
    {
        m_strName = name;
        m_strAddr = addr;
        cout << "People(...)\n";
    }
    void info()
    {
        cout << "name:" << m_strName << " addr:" << m_strAddr << endl;
    }
    string m_strName;
private:
    const string m_strId;
    const string m_strBorn;
    string m_strAddr;
};
//虚继承
//系统会自动生成一个虚继承表
//类中会自动生成一个指针
//该指针指向虚继承表
//该类可以通过虚继承表间接的访问虚继承的基类的数据
class Student: virtual public People
{
public:
    //继承过来的基类数据的初始化必须在派生类中的初始化列表中
    //调用基类的构造函数来初始化
    //若没有调用,则默认调用基类的无参构造函数来初始化
    Student(){cout << "Student()\n";}
    Student(string id, string name, string born, string addr, string stuid, float score)
     : People(id, name, born, addr)
    {
        m_strStuId = stuid;
        m_fScore = score;
        cout << m_strName << endl;  
        cout << "Student(...)\n";
    }
private:
    string m_strStuId;
    float m_fScore;
};
//被虚继承的基类由最派生类真正继承
//被虚继承的基类数据由最派生类负责初始化
//在最派生类的初始化列表中调用基类的构造函数进行初始化,
//若没有调用则默认调用基类的无参构造函数初始化
class Teacher: virtual public People
{
public:
    Teacher(){cout << "teacher()\n";}
    Teacher(string id, string name, string born, string addr, string level, float salary)
     : People(id, name, born, addr)
    {
        m_strLevel = level;
        m_fSalary = salary;
        cout << "Teacher(...)\n";
    }
private:
    string m_strLevel;
    float m_fSalary;
};
//构造顺序:1,被虚继承的基类2,正常继承的类3,本身构造函数体
class GS: public Student, public Teacher
{
public:
    GS(){cout << "GS()\n";}
    GS(string id, string name, string born, string addr, string stuid, float score, string level, float salary, string degree)
    : Student(id, name, born, addr, stuid, score)
      , Teacher(id, name, born, addr, level, salary)
      , m_strDegree(degree), People(id, name, born, addr)
    {
        cout << "GS(...)\n";    
    }
private:
    string m_strDegree;
};

int main(void)
{
    cout << "people:" << sizeof(People) << endl;
    cout << "stu:" << sizeof(Student) << endl;  
    cout << "tec:" << sizeof(Teacher) << endl;  
    cout << "gs:" << sizeof(GS) << endl;    
    //GS gs;
    GS gs("1001", "zhangsan", "1990-01-12", "shanghai", "stu_001", 89, "讲师", 8000, "化学研究生");
    //gs.Student::info();
    //gs.Teacher::info();
    gs.info();

    return 0;
}
inherit.png
#include <iostream>
using namespace std;

class Shape
{
public:
    Shape(){}
    float area(){return 0;}
};
class Square: public Shape
{
public:
    Square(float w=0): m_fWidth(w)
    {}
    float area()
    {
        return m_fWidth*m_fWidth;
    }
private:
    float m_fWidth;
};
class Triangle: public Shape
{
public:
    Triangle(float b=0, float h=0)
    {
        m_fBottom = b;
        m_fHight = h;
    }
private:
    float m_fBottom;
    float m_fHight;
};
int main(void)
{
    Shape shape;
    Square sq(34);
    cout << "shape:" << shape.area() << " square:" << sq.area()<<endl;

    //派生类对象可以赋给基类的对象,反过来则不行
//  shape = sq;
//  cout << shape.area() << endl;
//  sq = shape;  // X

    return 0;
}
#include <iostream>
using namespace std;

class Shape
{
public:
    Shape(){}
    float area()
    {
        cout << "Shape::area()\n";
        return 0;
    }
};
class Square: public Shape
{
public:
    Square(float w=0): m_fWidth(w)
    {}
    float area()
    {
        cout << "Square::area()\n";
        return m_fWidth*m_fWidth;
    }
private:
    float m_fWidth;
};
class Triangle: public Shape
{
public:
    Triangle(float b=0, float h=0)
    {
        m_fBottom = b;
        m_fHight = h;
    }
private:
    float m_fBottom;
    float m_fHight;
};
int main(void)
{
    Shape shape;
    Square sq(34);
    cout << "shape:" << shape.area() << " square:" << sq.area()<<endl;
    //指针调用函数时受限于类型
    Shape *pshape = &sq;    
    pshape->area();
    //派生类对象的地址可以赋给基类的指针反过来则不行
    //Square *psquare = &shape;  // X

    return 0;
}
#include <iostream>
using namespace std;

class Shape
{
public:
    Shape(){}
    //虚函数
    //若类中存在虚函数
    //则程序运行时系统会自动生成一张虚函数表,表中存放类的虚函数的入口地址
    //类中会自动添加一个指针
    //该指针指向虚函数表
    //即该指针存放了虚函数表的地址
    //称之为虚函数表指针
    virtual float area()
    {
        cout << "Shape::area()\n";
        return 0;
    }
};
class Square: public Shape
{
public:
    Square(float w=0): m_fWidth(w)
    {}
    //若派生类中存在和基类虚函数A函数原型相同的函数B,则该B函数默认为虚函数
    //用派生类中的B函数入口地址覆盖掉虚函数表中的基类A虚函数的地址
    float area()
    {
        cout << "Square::area()\n";
        return m_fWidth*m_fWidth;
    }
private:
    float m_fWidth;
};
class Triangle: public Shape
{
public:
    Triangle(float b=0, float h=0)
    {
        m_fBottom = b;
        m_fHight = h;
    }
    float area()
    {
        cout << "Triangle::area()\n";
        return m_fBottom*m_fHight/2;
    }
private:
    float m_fBottom;
    float m_fHight;
};
void show(Shape *pshape)
{
    //通过指针调用函数时
    //若该函数是虚函数,则到虚函数表中查找该函数的入口地址,进而执行
    cout << pshape->area() << endl;
}
int main(void)
{
    cout << "shape:" << sizeof(Shape) << " square:" << sizeof(Square) << " triangle:" << sizeof(Triangle) << endl;
#if 0
    Shape shape;
    Square sq(4);
    Triangle tri(3, 4);

    show(&shape);
    show(&sq);
    show(&tri);
#endif
    return 0;
}
//上面有一段代码与之相同,这一段在继承时没有用virtual;
#include <iostream>
#include <string>
using namespace std;

class People
{
public:
    People(){cout << "People()\n";}
    People(string id, string name, string born, string addr)
    : m_strId(id), m_strBorn(born)
    {
        m_strName = name;
        m_strAddr = addr;
        cout << "People(...)\n";
    }
    void info()
    {
        cout << "name:" << m_strName << " addr:" << m_strAddr << endl;
    }
private:
    const string m_strId;
    string m_strName;
    const string m_strBorn;
    string m_strAddr;
};
class Student: public People
{
public:
    //继承过来的基类数据的初始化必须在派生类中的初始化列表中调用基类的构造函数来初始化
    //若没有调用,则默认调用基类的无参构造函数来初始化
    Student(){cout << "Student()\n";}
    Student(string id, string name, string born, string addr, string stuid, float score)
     : People(id, name, born, addr)
    {
        m_strStuId = stuid;
        m_fScore = score;
        cout << "Student(...)\n";
    }
private:
    string m_strStuId;
    float m_fScore;
};
class Teacher: public People
{
public:
    Teacher(){cout << "teacher()\n";}
    Teacher(string id, string name, string born, string addr, string level, float salary)
     : People(id, name, born, addr)
    {
        m_strLevel = level;
        m_fSalary = salary;
        cout << "Teacher(...)\n";
    }
private:
    string m_strLevel;
    float m_fSalary;
};

class GS: public Student, public Teacher
{
public:
    GS(){cout << "GS()\n";}
    GS(string id, string name, string born, string addr, string stuid, float score, string level, float salary, string degree)
    : Student(id, name, born, addr, stuid, score)
      , Teacher(id, name, born, addr, level, salary)
      , m_strDegree(degree) 
    {
        cout << "GS(...)\n";    
    }
private:
    string m_strDegree;
};
int main(void)
{
    cout << "people:" << sizeof(People) << endl;
    cout << "stu:" << sizeof(Student) << endl;  
    cout << "tec:" << sizeof(Teacher) << endl;  
    cout << "gs:" << sizeof(GS) << endl;    
    //GS gs;
    GS gs("1001", "zhangsan", "1990-01-12", "shanghai", "stu_001", 89, "讲师", 8000, "化学研究生");
    gs.Student::info();
    //gs.Teacher::info();

    return 0;
}
#include <iostream>
#include <string>
using namespace std;

class People
{
public:
    People(){cout << "People()\n";}
    People(string id, string name, string born, string addr)
    : m_strId(id), m_strBorn(born)
    {
        m_strName = name;
        m_strAddr = addr;
        cout << "People(...)\n";
    }
    void info()
    {
        cout << "name:" << m_strName << " addr:" << m_strAddr << endl;
    }
protected:
    string m_strPhone;
private:
    const string m_strId;
    string m_strName;
    const string m_strBorn;
    string m_strAddr;
};
//class Student: public People
//class Student: protected People
//class Student: People
class Student: private People
{
public:
    //继承过来的基类数据的初始化必须在派生类中的初始化列表中调用基类的构造函数来初始化
    //若没有调用,则默认调用基类的无参构造函数来初始化
    Student(){cout << "Student()\n";}
    Student(string id, string name, string born, string addr, string stuid, float score)
     : People(id, name, born, addr)
    {
        m_strStuId = stuid;
        m_fScore = score;
        //cout << m_strName << endl;  // X
        cout << m_strPhone << endl;
        cout << "Student(...)\n";
    }
#if 0
    void info()
    {
    }
#endif
    void test()
    {
        info();
        //cout << m_strPhone << endl;
    //  cout << m_strName << endl;
    }
private:
    string m_strStuId;
    float m_fScore;
};
int main(void)
{
    Student s("101011", "zhangsan", "1900-10-10", "shanghai", "stu-001", 89);
    s.test();
    //s.info();
    //cout << s.m_strName << endl;// X
    //cout << s.m_strPhone << endl;  // X

    return 0;
}
#include <iostream>
#include <string>
using namespace std;

class People
{
public:
    People(){}
    People(string id, string name)
        : m_strId(id), m_strName(name)
    {}
    virtual void info()
    {
        cout << "id:" << m_strId << " name:" << m_strName << endl;
    }
private:
    string m_strId;
    string m_strName;
};
class Student: public People
{
public:
    Student(){}
    Student(string id, string name, float score)
        : People(id, name)
    {
        m_fScore = score;
    }
    void info()
    {
        People::info();
        cout << "score:" << m_fScore << endl;
    }
private:
    float m_fScore;
};
class Teacher: public People
{
public:
    Teacher(){}
    Teacher(string id, string name, string level, float salary)
        : People(id, name)
    {
        m_strLevel = level;
        m_fSalary = salary;
    }
    void info()
    {
        People::info();
        cout << "level:" << m_strLevel << " salary:" << m_fSalary << endl;
    }
private:
    string m_strLevel;
    float m_fSalary;
};
class Node
{
public:
    Node(People *people)
    {
        m_people = people;
        m_next = NULL;
    }
    People *m_people;
    Node *m_next;
};
class Link
{
public:
    Link()
    {
        m_pFirstNode = NULL;
        m_iLen = 0;
    }
    void insert(People *people)
    {
        Node *node = new Node(people);
        node->m_next = m_pFirstNode;
        m_pFirstNode = node;
        m_iLen++;
    }
    void show()
    {
        Node *node = m_pFirstNode;
        while (NULL != node)
        {
            node->m_people->info();
            node = node->m_next;
        }
    }
private:
    Node *m_pFirstNode;
    int m_iLen;
};
int main(void)
{
    Link link;
    link.insert(new People("100102", "zhangsan"));
    link.insert(new Student("1019e01", "lisi", 89));
    link.insert(new Teacher("1829e11", "kongzi", "jiaoshou", 89090));
    link.show();

    cout << "Hello World" << endl;
    return 0;
}
#include <iostream>
using namespace std;
class Test
{
public:
    Test(int a=90)
     : m_j(a), m_i(m_j)
    {}
    //普通成员变量的初始化顺序和在初始化列表中的顺序无关,和申明定义的顺序保持一致
    int m_i;
    int m_j;
};
int main(void)
{
    Test t(190);
    cout << t.m_i << ' ' << t.m_j << endl;
    return 0;
}
#include <iostream>
using namespace std;

class A
{
public:
    A(){cout << "A()\n";}
    ~A(){cout << "~A()\n";}
};
class B
{
public:
    B(){cout << "B()\n";}
    ~B(){cout << "~B()\n";}
};
//多继承情况下,基类的构造顺序和在初始化列表中调用基类构造函数的先后顺序无关,与继承的先后顺序保持一致,谁写在前面先构造谁
class Test: public A, public B
{
public:
    Test()
     : B(), A()
    {cout << "Test()\n";}
    ~Test()
    {cout << "~Test()\n";}
};
int main(void)
{
    Test t;
    return 0;
}
#include <iostream>
using namespace std;
#define PI 3.14
class Circle
{
public:
    Circle(float radius)
        : m_fRadius(radius)
    {
        cout << "Circle(...)" << endl;
    }
    virtual float area()
    {
        cout << "Circle::area()" << endl;
        return PI*m_fRadius*m_fRadius;
    }
    virtual float volume()
    {
        cout << "Circle::volume()" << endl;
        return 0;
    }
    float getRadius()
    {
        return m_fRadius;
    }
private:
    float m_fRadius;    
};
class Sphere: public Circle
{
public:
    Sphere(float radius): Circle(radius)
    {
        cout << "Sphere(...)" << endl;
    }
    virtual float area()
    {
        cout << "Sphere::area()" << endl;
        //4PI*R*R
        return 4*PI*getRadius()*getRadius();
    }
    virtual float volume()
    {
        cout << "Sphere::volume()" << endl;
        float radius = getRadius();
        return PI*radius*radius*radius*4/3;
    }
private:
};
class Column: public Circle
{
public:
    Column(float radius, float h)
        : Circle(radius)
    {
        m_fHight = h;
        cout << "Column(...)" << endl;
    }
    virtual float area()
    {
        cout << "Column::area()" << endl;
        float radius = getRadius();
        return PI*radius*radius*2 + 2*PI*radius*m_fHight;
    }
    virtual float volume()
    {
        cout << "Column::volume()" << endl;
        float radius = getRadius();
        return PI*radius*radius*m_fHight;
    }
private:
    float m_fHight;
};
void show(Circle &circle)
{
    cout << circle.area() << ' ' << circle.volume() << endl;
}
int main(void)
{
    Sphere sphere(2);
    show(sphere);

    Column column(2, 5);
    show(column);

    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,513评论 1 51
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 7,085评论 0 62
  • 一、 C/C++程序基础 面试例题1——分析代码写输出(一般赋值语句的概念和方法)。 面试例题2—...
    LuckTime阅读 1,970评论 2 42
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • 因为各种缘故,初六特意和女伴去无锡走了一遭。 从到无锡落地一直回上海,感觉这地方就是一个小城镇的感觉,城市建设相当...
    沈闲庭阅读 35,111评论 6 7