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} };
}