友元函數(shù)
作用:普通函數(shù)通過友元可以訪問一個(gè)類的私有或者保護(hù)數(shù)據(jù),以提高效率
//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;
//若將一個(gè)類申明為友元,
//則在該類所有函數(shù)中都可以訪問Boy的私有數(shù)據(jù)
friend class Girl;
//若將一個(gè)類中的某個(gè)成員函數(shù)申明為友元
//則只能在該函數(shù)中訪問Boy的私有數(shù)據(jù)
//friend void Girl::getBoyName(Boy &boy);
//友元函數(shù)
//在友元函數(shù)可以通過對(duì)象直接訪問和操作該對(duì)象的私有數(shù)據(jù)
//友元破壞了類的封裝性,盡量不要用
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;
}
運(yùn)算符重載
#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
//函數(shù)名: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;
}
?
虛函數(shù)
用于多態(tài)
#include <iostream>
#include <string>
using namespace std;
class Shape
{
public:
//虛函數(shù)
//虛函數(shù)主要用于多態(tài)
//若一個(gè)類中含有虛函數(shù)
//則系統(tǒng)會(huì)自動(dòng)的創(chuàng)建一個(gè)表,
//該表用于存放虛函數(shù)的入口地址
//稱該表為虛函數(shù)表
//該類會(huì)自動(dòng)添加一個(gè)指針,
//該指針存放虛函數(shù)表的首地址
//稱該指針為虛函數(shù)表指針
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;
}
//若派生類中存在和基類虛函數(shù)函數(shù)原型相同的函數(shù)
//則該派生類函數(shù)默認(rèn)為虛函數(shù)
//系統(tǒng)會(huì)自動(dòng)的用該派生類函數(shù)的地址
//覆蓋掉虛函數(shù)表中和其函數(shù)原型相同的基類的虛函數(shù)的地址
float getArea()
{
return m_fWidth * m_fHeight;
}
//類中定義的普通函數(shù)默認(rèn)為inline函數(shù)
//靜態(tài)成員函數(shù),虛函數(shù),構(gòu)造函數(shù),析構(gòu)函數(shù)不能為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)
{
//通過基類的指針或者引用來調(diào)用函數(shù)時(shí)
//若該函數(shù)為虛函數(shù),則到虛函數(shù)表中查找其入口地址
//獲得地址后,轉(zhuǎn)到該地址執(zhí)行函數(shù)
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;
}
純虛函數(shù)
#include <iostream>
#include <string>
using namespace std;
class Shape
{
public:
//純虛函數(shù)
//實(shí)現(xiàn)多態(tài),實(shí)現(xiàn)沒有意義--》定義為純虛函數(shù)
//含有純虛函數(shù)的類稱之為抽象類
//抽象類不能定義對(duì)象
//若派生類中,沒有對(duì)純虛函數(shù)進(jìn)行定義
//則該派生類仍然為抽象類,不能定義對(duì)象
//如果想用派生類生成對(duì)象,
//則在派生類中必須對(duì)純虛函數(shù)進(jìn)行定義
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;
}
異質(zhì)鏈表
? 將多個(gè)不同的對(duì)象,保存在一個(gè)鏈表上
//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, "三年級(jí)");
stuLink.insert(&s1);
Student s2("1002", "bb", 14, 89, 98, "三年級(jí)");
stuLink.insert(&s2);
Student s3("1003", "cc", 15, 89, 98, "三年級(jí)");
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();
}
}