C++11 类型转换

#include<iostream>
#include<string>
using namespace std;

//类型转换
void Insert(size_t pos, char ch)
{
	size_t _size = 5;
	//....
	int end = _size - 1;
	while (end >= pos) // end隐式类型转换
	{
		//_str[end + 1] = _str[end];
		--end;
	}
}
void Test1()
{
	int i = 1;
	// 隐式类型转换(意义相近的类型)
	double d = i;
	printf("%d, %.2f\n", i, d);

	int* p = &i;
	// 显示的强制类型转换(意义不相近的类型,值转换后有意义)
	int address = (int)p;

	printf("%x, %d\n", p, address);

	Insert(3, 'a');
	Insert(0, 'a');
}
int main()
{
	Test1();
	return 0;
}

 

是会有一点问题的。

static_cast 支持相近类型的转换
reinterpret_cast支持不相近类型的转换


int main()
{
	double d = 12.34;
	int a = static_cast<int>(d);
	cout << a << endl;

	int* p = &a;
	// 不支持的
	//int address = static_cast<int>(p);
	int address = reinterpret_cast<int>(p);

	return 0;
}

 

要小心使用的const_cast

int main()
{
	const int a = 2;
	int* p = const_cast<int*>(&a);
	*p = 3;

	cout << a << endl;  
	cout << *p << endl;  

	return 0;
}

这是控制台结果,我们还可以看一下监视和反汇编

 

从反汇编我们可以看到a直接呗替换成了常量 2

监视窗口下我们发现 a和*p的值都是2 

 

这都源于编译器对代码进行的优化

我们通过添加volatile关键字来取消这种优化

int main()
{
	/*const int a = 2;*/
	volatile const int a = 2;
	int* p = const_cast<int*>(&a);
	*p = 3;

	cout << a << endl;  
	cout << *p << endl;  

	return 0;
}

 

 

 

dynamic_cast

class A
{
public:
	virtual void f(){}
public:
	int _a = 0;
};

class B : public A
{
public:
	int _b = 1;
};

// A*指针pa有可能指向父类,有可能指向子类
void fun(A* pa)
{
	// 如果pa是指向子类,那么可以转换,转换表达式返回正确的地址
	// 如果pa是指向父类,那么不能转换,转换表达式返回nullptr
	B* pb = dynamic_cast<B*>(pa); // 安全的
	//B* pb = (B*)pa;             // 不安全
	if (pb)
	{
		cout << "转换成功" << endl;
		pb->_a++;
		pb->_b++;
		cout << pb->_a << ":" << pb->_b << endl;
	}
	else
	{
		cout << "转换失败" << endl;
		pa->_a++;
		cout << pa->_a << endl;
	}
}
int main()
{
	A aa;
	// 父类对象无论如何都是不允许转换成子类对象的
	/*B bb = dynamic_cast<B>(aa);
	B bb = (B)aa;*/
	B bb;

	fun(&aa);
	fun(&bb);
	//fun(nullptr);

	return 0;
}

C的这种用法hi能出结果,(运行不会被中断的)

class A1
{
public:
	//virtual void f(){}
public:
	int _a1 = 0;
};

class A2
{
public:
	//virtual void f(){}
public:
	int _a2 = 0;
};

class B : public A1, public A2//多继承
{
public:
	int _b = 1;
};

int main()
{
	B bb;
	A1* ptr1 = &bb;
	A2* ptr2 = &bb;
	cout << ptr1 << endl;
	cout << ptr2 << endl << endl;

	B* pb1 = (B*)ptr1;
	B* pb2 = (B*)ptr2;
	cout << pb1 << endl;
	cout << pb2 << endl << endl;
 

	return 0;
}

 但是我们观察一下对象内部的成员

IO流

int main()
{
	 //2023 8 29
	 //输入多个值,默认都是用空格或者换行分割
	int year, month, day;
	cin >> year >> month >> day;
	scanf("%d%d%d", &year, &month, &day);
	scanf("%d %d %d", &year, &month, &day); //不需要去加空格
	return 0;
}

三种写法都是可以的

处理连续型


int main()
{
	int year, month, day;
	scanf("%4d%2d%2d", &year, &month, &day);
	string str;

	cin >> str;
	year = stoi(str.substr(0, 4));
	month = stoi(str.substr(4, 2));
	day = stoi(str.substr(6, 2));
	return 0;
}

格式必须正确

 

类型转换


int main()
{
	// 内置类型 转换成自定义类型
	A aa1 = 1; // 隐式类型转换 用1构造A临时对象,再拷贝构造aa1,优化后直接1构造aa1

	// 自定义类型 转换成内置类型
	int i = aa1;

	return 0;
}


class Date
{
	friend ostream& operator << (ostream& out, const Date& d);
	friend istream& operator >> (istream& in, Date& d);
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

	operator bool()
	{
		// 这里是随意写的,假设输入_year为0,则结束
		if (_year == 0)
			return false;
		else
			return true;
	}
private:
	int _year;
	int _month;
	int _day;
};

istream& operator >> (istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

ostream& operator << (ostream& out, const Date& d)
{
	out << d._year << " " << d._month << " " << d._day;
	return out;
}

 C++ IO流,使用面向对象+运算符重载的方式
 能更好的兼容自定义类型,流插入和流提取
int main()
{
	// 自动识别类型的本质--函数重载
	// 内置类型可以直接使用--因为库里面ostream类型已经实现了
	int i = 1;
	double j = 2.2;
	cout << i << endl;
	cout << j << endl;

	// 自定义类型则需要我们自己重载<< 和 >>
	Date d(2022, 4, 10);
	cout << d;
	while (d)
	{
		cin >> d;
		cout << d;
	}

	return 0;
}

将test.cpp的内容打印到控制台上

int main()
{
	ifstream ifs("test.cpp");
	char ch = ifs.get();
	while (ifs)
	{
		cout << ch;
		ch = ifs.get();
	}

	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值