本节推荐多看示例代码
特殊类
不允许拷贝的类
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;
}