特殊类&类型转换

本节推荐多看示例代码

特殊类

不允许拷贝的类

default 拷贝&拷贝构造函数

只允许在堆上建立本对象的类

构造,拷贝构造,都放到private,提供static函数创建堆上对象

不允许继承的类

final修饰类

只能创建一个对象的类

不用计数法

恶汉模式

程序开始时自动创建一个对象,后封死构造/拷贝构造(类内有静态自身对象)

缺点:

  •  1、多个饿汉模式的单例,某个对象初始化内容较多(读文件),会导致程序启动慢
  •  2、A和B两个饿汉,对象初始化存在依赖关系,要求A先初始化,B再初始化,饿汉无法保证

class InfoMgr
{
public:
	static InfoMgr& GetInstance()
	{
		return _ins;
	}

	void Print()
    {		
        cout << _ip << endl;
		cout << _port << endl;
		cout << _buffSize << endl;
	}
private:
	InfoMgr(const InfoMgr&) = delete;
	InfoMgr& operator=(const InfoMgr&) = delete;

	InfoMgr()	{
		cout << "InfoMgr()" << endl;
	}
private:
	string _ip = "127.0.0.1";
	int _port = 80;
	size_t _buffSize = 1024 * 1024;
	//...

	static InfoMgr _ins;
};

InfoMgr InfoMgr::_ins;

懒汉模式

第一次调用时创建对象

定义指针pin,创建该对象时,如果pin为空则创建对象

或:自制函数内定义static本身对象, 不会造成无线循环构造

(局部静态是在第一次运行时才构造初始化)

推荐使用懒汉模式

class InfoMgr
{
public:
	static InfoMgr& GetInstance()
	{
		// 第一次调用时创建单例对象
		// 线程安全的风险
		if (_pins == nullptr)
		{
			_pins = new InfoMgr;
		}

		return *_pins;
	}

	void Print()
	{
		cout << _ip << endl;
		cout << _port << endl;
		cout << _buffSize << endl;
	}

	static void DelInstance()
	{
		delete _pins;
		_pins = nullptr;
	}

private:
	InfoMgr(const InfoMgr&) = delete;
	InfoMgr& operator=(const InfoMgr&) = delete;

	InfoMgr()
	{
		cout << "InfoMgr()" << endl;
	}
private:
	string _ip = "127.0.0.1";
	int _port = 80;
	size_t _buffSize = 1024 * 1024;
	//...

	static InfoMgr* _pins;
};

InfoMgr* InfoMgr::_pins = nullptr;

类型转换

explict 构造函数 可防止类的隐试类型转换

自定义&内置类型

类内实现强制类型转换函数

operator()被仿函数调用,只能下面写法:

operator 返回类型()

{函数体}

将强转类型视为操作符,且不用写函数返回类型

调用:(强转类型)objname

 //1、自定义类型 = 内置类型  ->构造函数支持
 //2、内置类型 = 自定义类型
class A
{
public:
	//explicit A(int a)
	A(int a)
		:_a1(a)
		,_a2(a)
	{}

	A(int a1, int a2)
		:_a1(a1)
		, _a2(a2)
	{}

	// ()被仿函数占用了,不能用
	// operator 类型实现,无返回类型
 	//explicit operator int()
	operator int()
	{
		return _a1 + _a2;
	}
private:
	int _a1 = 1;
	int _a2 = 1;
};
int main()
{
	string s1 = "1111111";
	A aa1 = 1;
	//A aa1 = (A)1;
	A aa2 = { 2,2 };
	const A& aa3 = { 2,2 };

	int z = aa1.operator int();
	//int x = (int)aa1;
	int x = aa1;
	int y = aa2;
	cout << x << endl;
	cout << y << endl;

	std::shared_ptr<int> foo;
	std::shared_ptr<int> bar(new int(34));

	//if (foo.operator bool())
	if (foo)
		std::cout << "foo points to " << *foo << '\n';
	else 
		std::cout << "foo is null\n";

	if (bar)
		std::cout << "bar points to " << *bar << '\n';
	else
		std::cout << "bar is null\n";

	return 0;
}

自定义类型&自定义类型

依靠构造函数实现

不算权限缩小:权限缩小和引用只限于指针与引用,不可普通对象与const对象

 c、自定义类型和自定义类型之间 -- 对应的构造函数支持
class A
{
public:
	A(int a)
		:_a1(a)
		, _a2(a)
	{}

	A(int a1, int a2)
		:_a1(a1)
		, _a2(a2)
	{}

	int get() const
	{
		return _a1 + _a2;
	}
private:
	int _a1 = 1;
	int _a2 = 1;
};

class B
{
public:
	B(int b)
		:_b1(b)
	{}

	B(const A& aa)
		:_b1(aa.get())
	{}

private:
	int _b1 = 1;
};

#include"List.h"
#include<list>

int main()
{
	A aa1(1);
	B bb1(2);

	bb1 = aa1;
	B& ref1= bb1;
	const B& ref2 = aa1;

	bit::list<int> lt = { 1,2,3,4 };
	// 权限的缩小?权限缩小和放大,仅限于const的指针和引用
	// 不是权限缩小,这里类型转换
	bit::list<int>::const_iterator cit = lt.begin();
	while (cit != lt.end())
	{
		cout << *cit << " ";
		++cit;
	}
	cout << endl;

	return 0;
}

static_cast  &  reinterpret_cast & const_cast & dynamic_cast

作用与不同运用场景:http://t.csdnimg.cn/Isqig

volatile 防止编译器将const对象变为宏,

dynamic_cast: 父转子返回空

int main()
{
	// 对应隐式类型转换 -- 数据的意义没有改变
	double d = 12.34;
	int a = static_cast<int>(d);
	cout << a << endl;
	
	// 对应强制类型转换 -- 数据的意义已经发生改变
	int* p1 = reinterpret_cast<int*>(a);

	// 对应强制类型转换中有风险的去掉const属性
	volatile const int b = 2;
	int* p2 = const_cast<int*>(&b);
	*p2 = 3;

	cout << b << endl;
	cout << *p2 << endl;

	return 0;
}

RTTI

见:http://t.csdnimg.cn/zaI3b

板书

  • 20
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值