c++的四种转换方式,完美转发底层如何实现,移动构造语句底层如何实现,auto推演,NULL和nullptr,C++的统一的初始化方案

c++的四种转换方式

c语言的转换方式

int main()
{
	int a = 10;
	const int b = 20;
	int* pa = &a;
	int* pb = (int*) &b;//不清楚转换的目的

	float ft = 12.23;
	a = (int)ft;
	float* fp = &ft;
	int* ip = (int*)fp;//不清楚转换的目的
}
基本的数据类型转换
int main()
{
	int a = 20;
	float ft = 12.23;

	a = static_cast<int>(ft);//目的是基本的数据类型转换
	ft = static_cast<float>(a);//ft=(float)a;
	return 0;
}

去常性转换
int main()
{
	const int a = 10;
	int* p = const_cast<int*>(&a);//目的是去常性
	//p = static_cast<int*>(&a); erro

}
指针的转换
int main()
{
	int a = 10;
	int* p = &a;
	//指针的转换
	char* cp = reinterpret_cast<char*>(&a);
}

class Object
{
public:
	virtual void fun() {}
};
class Base :public Object
{
public:
	virtual void fun();
};

动态转换
int main()
{
	Object* op = NULL;
	Base* bp = NULL;
	Object obj;
	Base base;

	op = &base;
	//pb = &obj;err
	op = dynamic_cast<Object*>(&base);
    //只能将子类对象给父类指针
	return 0;
}

移动构造语句底层如何实现

class MyString
{
	char* str;
public:
	MyString(const char* p = NULL):str(NULL)
	{
		if (p!= NULL)
		{
			int len = strlen(p) + 1;
			str = new char[len];
			strcpy_s(str, len, p);
		}
	}
	MyString(const MyString& s) :str(NULL)
	{
		if (s.str != NULL)
		{
			int len = strlen(s.str) + 1;
			str = new char[len];
			strcpy_s(str, len, s.str);
		}
	}
	MyString(MyString&& s) :str(s.str)
	{
		s.str = NULL;
	}
	~MyString()
	{
		if (str != NULL)
		{
			delete []str;
		}
		str = NULL;
	}
};

template<class _Ty>
struct my_remove_reference
{
	using type = _Ty;
	using _Const_thru_ref_type = const _Ty;
};
template<class _Ty>
struct my_remove_reference<_Ty&>
{
	using type = _Ty;
	using _Const_thru_ref_type = const _Ty&;
};
template<class _Ty>
struct my_remove_reference<_Ty&&>
{
	using type = _Ty;
	using _Const_thru_ref_type = const _Ty&&;
};
template<class _Ty>
using my_remove_reference_t = typename my_remove_reference<_Ty>::type;

template<class _Ty>
my_remove_reference_t<_Ty>&& my_move(_Ty&& _Arg)
{
	return static_cast<my_remove_reference_t<_Ty&&>>(_Arg);
}
int main()
{
	/*
	MyString s1("lijiangli");
	MyString s2(s1);
	//移动赋值
	MyString s3(std::move(s1));//s1怎样知道是调动的移动拷贝构造函数
	//MyString s3((MyString&&)s1);
   */
	MyString s1("lijianli");
	const MyString& s2 = s1;
	MyString&& ss = MyString("hello");
	MyString s3(my_move(s2));
	MyString s4(my_move(s1));
	return 0;
}
int &&x=19;
const int &&y=20;//不是右值引用,系统认为它是const int&

多线程的内存池的一些想法

template<int inst>
class Base
{
protected:
	static int num;
public:
	Base()
	{
		num += 1;
	}
	int Getnum() { return num; }
};
template<int inst>
int Base<inst>::num = 0;

int main()
{
	//inst不同产生的对象的版本不同
	Base<0>b1;
	Base<0>b2;
	cout << b1.Getnum() << endl;
	Base<1>c1;
	Base<1>c2;
	Base<1>c3;
	cout << c1.Getnum() << endl;
	return 0;
}

在这里插入图片描述

void print(int& a)
{
	cout << "int&" << endl;
}
void print(const int& a)
{
	cout << "const int&" << endl;
}
void print(int &&a)
{
	cout << "int&&" << endl;
}
template<class _Ty>
void fun(_Ty&& a)
{
	//这里没有左右值之说全是左值
	print(a);
	print(std::forward<_Ty>(a));
}
int main()
{
	int a = 10;
	int& b = a;
	int&& c = 10;
	const int& d = a;
	fun(a);
	fun(b);
	fun(c);
	fun(d);
	fun(20);
	return 0;
}

在这里插入图片描述

完美转发底层如何实现

template<class _Ty>
struct my_remove_reference
{
	using type = _Ty;
	using _Const_thru_ref_type = const _Ty;
};
//部分特化版本
template<class _Ty>
struct my_remove_reference<_Ty&>
{
	using type = _Ty;
	using _Const_thru_ref_type = const _Ty&;
};
template<class _Ty>
struct my_remove_reference<_Ty&&>
{
	using type = _Ty;
	using _Const_thru_ref_type = const _Ty&&;
};
template<class _Ty>
using my_remove_reference_t = typename my_remove_reference<_Ty>::type;

template<class _Ty>
my_remove_reference_t<_Ty>&& my_move(_Ty&& _Arg)
{
	return static_cast<my_remove_reference_t<_Ty>&&>(_Arg);
} 

template<class _Ty>
_Ty&& my_forward(my_remove_reference_t<_Ty>& _Arg) 
{
	return static_cast<_Ty&&>(_Arg);
}
template<class _Ty>
_Ty&& my_forward(my_remove_reference_t<_Ty>&& _Arg) 
{
	return static_cast<_Ty&&>(_Arg);
}
void print(int& a)
{
	cout << "int&" << endl;
}
void print(const int& a)
{
	cout << "const int&" << endl;
}
void print(int &&a)
{
	cout << "int&&" << endl;
}
template<class _Ty>
void fun(_Ty&& a)
{
	//这里没有左右值之说全是左值
	print(a);
	print(std::forward<_Ty>(a));
	print(my_forward<_Ty>(a));
}

int Add(int a, int b)
{
	return a + b;
}
//&+&=>&
//&&+&=>&
//&+&&=>&
//&&+&&=>&&
int main()
{
	int a = 10;
	int& b = a;
	int&& c = 10;
	const int& d = a;
	fun(a);
	fun(b);
	fun(c);
	fun(d);
	fun(20);
	return 0;
}

auto推演

//c11 auto类型推演
int main()
{
	auto x = 10;//auto int
	auto p = new int(10);//auto int *
	auto* s = new int(10);//auto  int
	//auto定义变量时必须进行初始化
	//auto r;erro
	auto ar[]={12,23,34};//erro
}
class Base
{
	//auto val;//erro
	static const auto num = 0;//ok
};

void fun(auto a)//不允许auto 作为函数参数
{
}

int main()
{
	int x = 10;//
	auto* a = &x;//auto int
	auto b = &x;//auto int *
	auto& c = x;//auto int(&和c绑定)
	const int e = 10;
	auto f = e;//auto int(将const省略)
	auto& f2 = e;//auto const int
}

template<class T>
const T& Add(const T&,const T& b)
{
 return a+b;
}
int main()
{
 std::map<int,string>ismap;
 auto it=ismap.begin();
 auto =Add(12,23);//auto可以推演返回值的类型
}

预估值方案

//预给值方案
class Test
{
	int val = 0;
	int *str = NULL;
public:
	Test() = default;
	Test(int x = 10) :val(x), str(NULL) {}
};
int main()
{
	//Test t;没有构造函数之前采用预给值
	Test t1(10);
	Test t2(20);
	return 0;
}

decltype类型推导

int add(int a, int b)
{
	return a + b;
}
//decltype;根据表达式推演出类型
int main()
{
	int a= 10;
	decltype(a)b = 20;
	decltype (a + b)c = 30;
	decltype(add(12, 23))c = 30;
	return 0;
}

NULL与nullptr

void fun(char*)
{
	cout << "fun(char*)" << endl;
}
void fun(int a)
{
	cout << "fun(int a)" << endl;
	cout << a << endl;
}
//nullptr与NULL
/*
 如果是c++NULL为 0
 否则为((void *)))
 具有二义性,为了解决该问题C11提出了nullptr它是空指针常量
*/
int main()
{
	fun(0);
	fun(NULL);
    fun(nullptr);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

统一的初始化方案{}

//C++为了使用模板,有一种统一的初始化方案
int main()
{
	int a = 10;
	int b(10);
	int c = int(0);

	int c{0};
	int d = { 0 };
	int* p = &a;
	int* s{ &a };
	int* r = { &a };
	int* ip{ nullptr };
}

class Object
{
	int value;
public:
	Object(int x=0) :value(x) {}
	Object(int x, int y) :value(x + y) {}
};
vector<int>add()
{
	return { 1,2,3,4 };
}
int main()
{
	int* p = new int{0};
	int* s = new int[] {1, 2, 3, 4};
	Object a();//函数的声明,不产生对象
	Object();//产生无名对象
	Object obja{ 0 };
	Object objb();//没有创建方案,只是函数的声明,之所以用{}就是为了躲避函数的声明
	Object objc{};
	Object* op = new Object[]{ 1,2,3,4,5 };
	Object* op2 = new Object[]{ {1,2},{3,4},{5,6} };
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值