[C++ 面向对象高级编程]知识点补充1

[C++ 面向对象高级编程]知识点补充1

文章概述

该文章为 侯捷教授的 C++ 面向对象高级编程 课程,主要进行一些知识点补充说明包含一下几个知识点

  1. static
  2. class template
  3. function template
  4. namespace

作者信息

NEFU 2020级 zsl
ID:fishingrod/鱼竿钓鱼干
Email:851892190@qq.com
欢迎各位引用此博客,引用时在显眼位置放置原文链接和作者基本信息

正文部分

static

首先来看普通的Complex类的成员函数real()

//省略了一些东西
class complex
{
	public:
		double real()const{return this->re;}
	//double real()const{return re;} this可写可不写,编译器自动补上
	private:
		double re,im;
}

调用过程

complex c1,c2,c3;
cout << c1.real();
cout << c2.real();

我们的类只有一个成员函数real(),为了知道谁要使用他就需要this来表明调用者。我们可以近似的认为上面函数进行了如下操作

complex::real(&c1);
complex::real(&c2);

接下来来看static的情况

class Account {
	public:
		static double m_rate;
		static void set_rate(const double& x) {m_rate = x);
};

double Account::m_rate = 8.0;//必须进行一个初始化的定义
int main(){
	Account::set_rate(5.0);//通过class name来调用

	Account a;
	a.set_rate(7.0);//通过object来调用
	return 0;
}

对于static的数据,是每个对象共享一份的。在操作static数据的时候需要注意以下几点。

  1. static数据需要static函数去操作,static函数只能处理静态的数据
  2. 通过对象调用static函数不会包含this指针
  3. static调用方式:通过object调用,通过class name调用
  4. static数据必须在class外面进行初始化的定义操作
static 在 Singleto单例设计模式中的应用

Singleton设计模式保证类只有一个实例,并且为系统提供一个全局访问点
一般会把构造函数放在private里并创建一个static数据

class A{
	public:
		static A& getInstance(){return a;};
		setup(){
		....
		}
	private:
		A();
		A(const A& rhs);
		static A a;
}


//调用
A::getInstance().setup();

上述代码的缺点是,无论使用调用到这个类都会创建一个static数据,为了优化这一点就,我们在接口函数中创建static数据,这样就只会在调用的时候才创建出来。

//改进版
class A{
	public:
		static A& getInstance();
		setup(){
		....
		}
	private:
		A();
		A(const A& rhs);
		...
}

A& A::getInstance(){
	static A a;
	return a;
}

class template 类模板

给只有数据不同的类写好几个不同的代码是在太过冗余和浪费时间了,为了处理这种问题,我们可以使用类模板来简化我们的代码。

template类模板会在调用的时候才指定具体的数据类型,使用方式如下

template<typename T>
class complex
{
	public:
		complex(T re,T im)
			:re(r),im(i)
		{}
		complex& operator +=(const complex&);
		T real()const{return re;}
		T real()const{return im;}
	private:
		double im,re;
}

complex<double>c1(2.5,1.5);
complex<int>c2(2,6);

function template

在这里插入图片描述对于函数模板,我们不需要用<>指定具体数据类型,编译器我们帮助我们按照一下步骤自动推导(以上图为例)

  1. 调用min函数,编译器根据实参推导T
  2. 推导得到T为stone类
  3. 调用stone类里的<重载函数

这么做的好处是责任的分离,具体如何比较大小的责任是有具体的数据类型去实现的而不是min函数去实现的

namespace

如果两个不同的库里有同样名称的函数,那么调用的时候编译器就不知道要用哪个了,namespace就是用来处理这种函数名冲突的问题的。
namespace相当于把函数之类的玩意包装起来了,如果你要使用就需要打开这个包装。
using directive

#include<iosteam>
using namespace std;

int main(){
	cin<<...;
	cout<<...;
}

using declaration

#include<iosteam>
using std::cout;

int main(){
	std::cin<<...;
	cout<<...;
}
#include<iosteam>

int main(){
	std::cin<<...;
	std::cout<<...;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值