友元函数,运算符重载,虚函数,纯虚函数,异质链表

友元函数

作用:普通函数通过友元可以访问一个类的私有或者保护数据,以提高效率

//boy.h
#ifndef BOY_H
#define BOY_H

#include <iostream>
#include <string>
#include "Girl.h"

using namespace std;

class Boy
{
public:
    Boy(){}
    Boy(string name, string phone, string face);

    string m_strFace;
    //若将一个类申明为友元,
    //则在该类所有函数中都可以访问Boy的私有数据
    friend class Girl;
    //若将一个类中的某个成员函数申明为友元
    //则只能在该函数中访问Boy的私有数据
    //friend void Girl::getBoyName(Boy &boy);

    //友元函数
    //在友元函数可以通过对象直接访问和操作该对象的私有数据
    //友元破坏了类的封装性,尽量不要用
    friend void fun(Boy &boy);

private:
    string m_strName;
    string m_strPhone;
};
void fun(Boy &boy);

#endif
//boy.cpp
#include "boy.h"

Boy::Boy(string name, string phone, string face)
{
    m_strName = name;
    m_strPhone = phone;
    m_strFace = face;
}

void fun(Boy &boy)
{
    cout << boy.m_strName << endl;
}
#ifndef GIRL_H
#define GIRL_H
//girl.h
#include <iostream>
#include <string>


using namespace std;

class Boy;

class Girl
{
public:
    void getBoyName(Boy &boy);
    void getBoyPhone(Boy &boy);
};

#endif
//girl.cpp
#include "Girl.h"
#include "boy.h"

void Girl::getBoyName(Boy &boy)
{
    cout << boy.m_strName << endl;
}
void Girl::getBoyPhone(Boy &boy)
{
    cout << boy.m_strPhone << endl;
}
//main.cpp
#include "boy.h"

int main(void)
{
    Boy boy("zhangsan", "11122334", "cool");
    fun(boy);

    Girl g;
    g.getBoyName(boy);

    return 0;
}

运算符重载

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

class Complex
{
public:
    Complex(int real = 0, int vir = 0)
    {
        m_iReal = real;
        m_iVir = vir;
    }
    void show()
    {
        cout << m_iReal << '+' << m_iVir << 'i' << endl;
    }
    friend Complex operator+(const Complex &c1
                             , const Complex &c2);
    friend Complex operator-(const Complex &c1
                             , const Complex &c2);
    friend bool operator>(const Complex &c1
                          , const Complex &c2);
private:
    int m_iReal;
    int m_iVir;
};

//返回值类型:Complex
//函数名:operator+
//形参列表:const Complex &c1, const Complex &c2
Complex operator+(const Complex &c1, const Complex &c2)
{
    Complex com;
    com.m_iReal = c1.m_iReal + c2.m_iReal;
    com.m_iVir = c1.m_iVir + c2.m_iVir;
    return com;
}
Complex operator-(const Complex &c1, const Complex &c2)
{
    Complex com;
    com.m_iReal = c1.m_iReal - c2.m_iReal;
    com.m_iVir = c1.m_iVir - c2.m_iVir;
    return com;
}

bool operator>(const Complex &c1, const Complex &c2)
{
    if (c1.m_iReal > c2.m_iReal 
        || ((c1.m_iReal == c2.m_iReal)
             &&(c1.m_iVir > c2.m_iVir)))
    {
        return true;
    }
    return false;
}

int main(void)
{
    Complex com(3, 4);
    com.show();

    Complex com2(4, 9);
    com2.show();

    //Complex com3 = com + com2;
    Complex com3 = operator+(com, com2);
    com3.show();
    
    //Complex com4 = com - com2;
    Complex com4 = operator-(com, com2);
    com4.show();

    if (com3 > com4)
    {
        cout << "com3 > com4" << endl;
    }
    else
    {
        cout << "com3 <= com4" << endl;
    }

    return 0;
}

虚函数

用于多态

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

class Shape
{
public:
    //虚函数
    //虚函数主要用于多态

    //若一个类中含有虚函数
    //则系统会自动的创建一个表,
    //该表用于存放虚函数的入口地址
    //称该表为虚函数表

    //该类会自动添加一个指针,
    //该指针存放虚函数表的首地址
    //称该指针为虚函数表指针
    virtual float getArea()
    //float getArea()
    {
        return 0;
    }
};

class Rectangle: public Shape
{
public:
    Rectangle(float w = 0, float h = 0)
    {
        m_fWidth = w;
        m_fHeight = h;
    }
    //若派生类中存在和基类虚函数函数原型相同的函数
    //则该派生类函数默认为虚函数
    
    //系统会自动的用该派生类函数的地址
    //覆盖掉虚函数表中和其函数原型相同的基类的虚函数的地址
    float getArea()
    {
        return m_fWidth * m_fHeight;
    }
    //类中定义的普通函数默认为inline函数
    //静态成员函数,虚函数,构造函数,析构函数不能为inline
    //inline void test() 
    void test() 
    {}
private:
    float m_fWidth;
    float m_fHeight;
};

class Triangle: public Shape
{
public:
    Triangle(float b = 0, float h = 0)
    {
        m_fBottom = b;
        m_fHeight = h;
    }
    float getArea()
    {
        return m_fBottom * m_fHeight / 2;
    }
private:
    float m_fBottom;
    float m_fHeight;
};
#if 1
//指针能够访问的范围受类型局限
//即只能访问该指针类型中的成员
void fun(Shape *pShape)
{
    //通过基类的指针或者引用来调用函数时
    //若该函数为虚函数,则到虚函数表中查找其入口地址
    //获得地址后,转到该地址执行函数
    cout << pShape->getArea() << endl;
//  pShape->test();  //error
}
#endif

int main(void)
{
    cout << sizeof(Shape) << endl;
    Rectangle rec(3,4);
//  cout << rec.getArea() << endl;
    fun(&rec);  
    Triangle tri(3,4);
//  cout << tri.getArea() << endl;
    fun(&tri);
    Shape sh;
//  cout << sh.getArea() << endl;
    fun(&sh);
    return 0;
}

纯虚函数

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

class Shape
{
public:
    //纯虚函数
    //实现多态,实现没有意义--》定义为纯虚函数
    //含有纯虚函数的类称之为抽象类
    //抽象类不能定义对象

    //若派生类中,没有对纯虚函数进行定义
    //则该派生类仍然为抽象类,不能定义对象

    //如果想用派生类生成对象,
    //则在派生类中必须对纯虚函数进行定义
    virtual float getArea() = 0;
};

class Rectangle: public Shape
{
public:
    Rectangle(float w = 0, float h = 0)
    {
        m_fWidth = w;
        m_fHeight = h;
    }
    float getArea()
    {
        return m_fWidth * m_fHeight;
    }
private:
    float m_fWidth;
    float m_fHeight;
};

class Triangle: public Shape
{
public:
    Triangle(float b = 0, float h = 0)
    {
        m_fBottom = b;
        m_fHeight = h;
    }
    float getArea()
    {
        return m_fBottom * m_fHeight / 2;
    }
private:
    float m_fBottom;
    float m_fHeight;
};
void fun(Shape *pShape)
{
    cout << pShape->getArea() << endl;
}

int main(void)
{
    Rectangle rec(3,4);
    fun(&rec);  
    
    Triangle tri(3,4);
    fun(&tri);
    
    return 0;
}

异质链表

​ 将多个不同的对象,保存在一个链表上

//link.h
#ifndef LINK_H
#define LINK_H

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

class Person
{
public:
    Person(){}
    Person(string id, string name, int age);
    virtual void info();
private:
    string m_strId;
    string m_strName;
    int m_iAge;
};

class Student: public Person
{
public:
    Student(){}
    Student(string id, string name, int age
            , float chinese, float math, string grade);
    void info();
private:
    float m_fChinese;
    float m_fMath;
    string m_strGrade;
};

class Teacher: public Person
{
public:
    Teacher(){}
    Teacher(string id, string name, int age
            , float salary, string course);
    void info();
private:
    float m_fSalary;
    string m_strCourse;
};

class Node
{
public:
    Node():m_pPerson(NULL), m_pNext(NULL){}
    Node(Person *pPerson);
    void show();
    Node* &next();
private:
    Person *m_pPerson;
    Node *m_pNext;
};

class Link
{
public:
    Link():m_iLen(0), m_pFirstNode(NULL){}
    void insert(Person *pPerson);
    void show();
private:
    int m_iLen;
    Node *m_pFirstNode;
};
#endif

//link.cpp
#include "link.h"

Person::Person(string id, string name, int age)
{
    m_strId = id;
    m_strName = name;
    m_iAge = age;
}
void Person::info()
{
    cout << m_strId << ' ' << m_strName 
         << ' ' << m_iAge << endl;
}

Student::Student(string id, string name, int age
            , float chinese, float math, string grade)
        : Person(id, name, age)
{
    m_fChinese = chinese;
    m_fMath = math;
    m_strGrade = grade;
}
void Student::info()
{
    Person::info();
    cout << "score:" << m_fChinese << ' ' << m_fMath
         << " grade:" << m_strGrade << endl;
}

Teacher::Teacher(string id, string name, int age
            , float salary, string course)
        : Person(id, name, age)
          , m_fSalary(salary), m_strCourse(course)
{
}

void Teacher::info()
{
    Person::info();
    cout << "course:" << m_strCourse 
         << " salary:" << m_fSalary << endl;
}

Node::Node(Person *pPerson)
          :m_pPerson(pPerson), m_pNext(NULL)
{}

void Node::show()
{
    m_pPerson->info();
}

Node* & Node::next()
{
    return m_pNext;
}

//main.cpp
#include "link.h"
int main(void)
{
    Link tecLink;
    Teacher t1("1001", "aa", 13, 9000, "语文");
    tecLink.insert(&t1);
    
    Teacher t2("1002", "bb", 13, 9000, "语文");
    tecLink.insert(&t2);
    
    Teacher t3("1003", "cc", 13, 9000, "语文");
    tecLink.insert(&t3);

    tecLink.show();
#if 0
    Link stuLink;

    Student s1("1001", "aa", 13, 89, 98, "三年级");
    stuLink.insert(&s1);
    
    Student s2("1002", "bb", 14, 89, 98, "三年级");
    stuLink.insert(&s2);
    
    Student s3("1003", "cc", 15, 89, 98, "三年级");
    stuLink.insert(&s3);

    stuLink.show();
#endif

    return 0;
}

void Link::insert(Person *pPerson)
{
    if (NULL != pPerson)
    {
        Node *pNode = new Node(pPerson);

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

推荐阅读更多精彩内容