C++面向对象笔记(6):模板篇

C++模板篇

本章主要的内容:

  1. 友元函数、友元类
  2. 静态数据成员、静态成员函数
  3. 运算符重载
  4. 模板函数+模板类==》标准模板类
  5. 标准模板库中向量Vector、链表list、映射map的使用

**注意:**关于友元,友元只是封装的补充,会破坏封装性,有定向暴露性(在实在没有办法的情况下使用友元)

1.友元函数-全局友元函数和友元成员函数

1.全局友元函数的定义和调用

class Time {
   
   
	// Time类的全局友元函数
    friend void printTime(Time &t);
    
public:
    Time(int hour, int min, int sec) {
   
   
        m_iHour = hour;
    	m_iMinute = min;
    	m_iSecond = sec;
    }
private:
    m_iHour = hour;
    m_iMinute = min;
    m_iSecond = sec;
};

// Time类的全局友元函数
void printTime(Time &t){
   
   
    cout << t.m_iHour << ":" 
        << t.m_iMinute << ":"  
        << t.m_iSecond << endl;
}

int main() {
   
   
    Time t(6,34,25);
    printTime(t);// 调用全局友元函数
    return 0;
}
/*输出:
6:34:25
*/

2.友元成员函数的定义和调用

  1. Match类-Match.h:
//#include "Time.h"

// 先声明有Time,代表之后会进行实现,但是不能使用include,会导致循环包含
class Time;

class Match {
   
   
public:
    void printTime(Time &t);
};

2.Match类-Match.cpp:

#include <iostream>
#include "Match.h"
#include "Time.h"// [!]不明白此处为何可以include,不会造成Match和Time的循环包含吗?

using namespace std;

void Match::printTime(Time &t) {
   
   
    cout << t.m_iHour << ":"
    << t.m_iMinute << ":"
    << t.m_iSecond << endl;
}

3.Time类-Time.h:

#include <iostream>
#include "Match.h"

using namespace std;

class Time {
   
   

    // 在这里声明友元函数,在此并不受本类的访问限定符限定,
    // 故写在public或private下并没有区别
    friend void Match::printTime(Time &t);

public:
    Time(int hour,int min,int sec);

private:
    int m_iHour;
    int m_iMinute;
    int m_iSecond;
};

4.Time类-Time.cpp:

#include "Time.h"

Time::Time(int hour, int min, int sec) {
   
   
    m_iHour = hour;
    m_iMinute = min;
    m_iSecond = sec;
}

5.main.cpp:

#include <iostream>
#include "Time.c"

int main() {
   
   
    Time t(6,34,25);
    Match m;
    m.printTime(t);// 调用友元函数
    
    return 0;
}
/*输出:
6:34:25
*/

2.友元类

友元类的写法:

由于编译器不同,友元类有两种写法:1、friend class 类名; 2、friend 类名

友元类的声明与使用举例

#include <iostream>
using namespace std;

// 事先加入Watch声明,代表当前没有实现,但是之后会进行实现
class Watch;

/**
 * 定义Time类
 * 数据成员:m_iHour, m_iMinute,m_iSecond 
 * 成员函数:构造函数
 * 友元类:Watch
 */
class Time{
   
   
    
    // 声明Time类是Match类的友元类,即声明Match有个友元类是Time
    // 所以Match就可以访问Time中的成员了
    friend class Watch;
    
public:
	Time(int hour, int min, int sec){
   
   
		m_iHour = hour;
		m_iMinute = min;
		m_iSecond = sec;
	}
public:
	int m_iHour;
	int m_iMinute;
	int m_iSecond;
};

/**
 * 定义Watch类
 * 数据成员:m_tTime
 * 成员函数:构造函数
 * display用于显示时间
 */
class Watch{
   
   
public:
	Watch(Time &timeObj) : m_tTime(timeObj){
   
   
	}
	void display(){
   
   
		cout << m_tTime.m_iHour << endl;
		cout << m_tTime.m_iMinute << endl;
		cout << m_tTime.m_iSecond << endl;
	}
public:
	Time m_tTime;
};


int main(){
   
   
	Time t(6, 30, 20);
	Watch w(t);
	w.display();

	return 0;
}

3.友元的总结

注意:

  1. 友元关系不可传递
  2. 友元关系得单向性(A是B的友元,不代表B是A的友元)
  3. 友元声明的形式及数量不受限制
  4. 友元只是封装的补充,会破坏封装性,有定向暴露性(在实在没有办法的情况下使用友元)
  5. 友元的声明不受访问限定符影响,可以声明在类中的任何位置。(即用friend修饰的声明,仅限被friend修饰的这一句话不受)

对于友元关系的记法

  1. 友元函数:friend在哪个类出现,则此函数就是这个类的朋友,这个函数就可以对这个类的所有数据成员进行访问了。(通过传入的对象的引用来进行访问)
  2. 友元类:friend在A类出现,则被friend修饰的B类就是这个类(A类)的朋友,所以B类就可以对A类中的所有数据成员进行访问了(直接通过B类进行调用即可,无需使用引用)。即在A类中出现friend修饰的B,那么B就是当前类的朋友,可以访问当前类。

4.静态变量与静态函数

静态成员依托于类,而不是对象,就算类没有实例化对象,静态成员也会存在于内存中。

假如有个类A,其中有静态变量cout,在实例化a,b,c,d之前,cout这个静态变量就已经存在于内存中 了。

静态变量:

声明:static int 变量名;

初始化(方法1):static int 变量名 = xxxx;(在类中声明+初始化)

初始化(方法2):int 类名::变量名 = xxxx;(在类外初始化)

访问(方法1):类名::变量名

访问(方法2):对象名.变量名指针名->变量名

静态函数:

初始化(方法1):static int 函数名(){xxxx;}(在类中初始化)

访问(方法1):类名::函数名()

访问(方法2):对象名.函数名()指针名->函数名()

int 类名::变量名 = xxxx

注意事项

  1. 静态数据成员必须单独初始化。(在对象实例化之前就有了,所以不能写到类的构造函数中去)
  2. 静态成员函数不能调用非静态成员函数和费静态数据成员。
  3. 静态数据成员只有一份,且不依赖对象而存在。

对于上面注意事项的第2点做一下原理补充:

在类中的普通成员函数中调用普通成员变量,实际上为了辨认出当前使用的变量属于哪个对象,都会自动添加this指针;如果是静态变量,因为不依托于对象,而是依托于类,所以不会自动添加this指针,如下所示:

void FunctionName(){
   
   
    variable1 = "01";	// 普通成员变量
    variable2 = "02";	// 静态成员变量
}
// 实际上会变成下面的这种形式
void FunctionName(ClassName *this){
   
   
    this-
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值