日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

一文帶你深入了解C++中的類型轉換_C 語言

作者:~小火苗 ? 更新時間: 2023-02-02 編程語言

C語言中的類型轉換

在C語言中,如果賦值運算符左右兩側類型不同,或者形參與實參類型不匹配,或者返回值類型與接收返回值類型不一致時,就需要發生類型轉化,C語言中總共有兩種形式的類型轉換:隱式類型轉換和顯式類型轉換。

1.隱式類型轉化:編譯器在編譯階段自動進行,能轉就轉,不能轉就編譯失敗

2.顯式類型轉化:需要用戶自己處理

3.缺陷:轉換的可視性比較差,所有的轉換形式都是以一種相同形式書寫,難以跟蹤錯誤的轉換

int main()
{
	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);

	return 0;
}

為什么C++需要四種類型轉換

C風格的轉換格式很簡單,但是有不少缺點的:

1.隱式類型轉化有些情況下可能會出問題:比如數據精度丟失

2.顯式類型轉換將所有情況混合在一起,代碼不夠清晰

因此C++提出了自己的類型轉化風格,注意因為C++要兼容C語言,所以C++中還可以使用C語言的轉化風格。

C++強制類型轉換

標準C++為了加強類型轉換的可視性,引入了四種命名的強制類型轉換操作符:

static_cast、 reinterpret_cast、 const_cast、 dynamic_cast

static_cast

static_cast用于非多態類型的轉換(靜態轉換),編譯器隱式執行的任何類型轉換都可用static_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); // 意義不相近
	return 0;
}

reinterpret_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

const_cast最常用的用途就是刪除變量的const屬性,方便賦值

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

	*p = 3;

	cout << a << endl;  // 2
	cout << *p << endl; // 3


	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;
	}
}
// A 是父類   B是子類
int main()
{
	// 父類對象無論如何都是不允許轉換成子類對象的
	// A aa;
	// B bb = dynamic_cast<B>(aa); // 不支持
	// B bb = (B)aa;               // 不支持

	A aa;
	B bb;
	A* pa = &bb;

	B* pb = dynamic_cast<B*>(pa);

	//fun(nullptr);
	return 0;
}

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;

	B* pb3 = dynamic_cast<B*>(ptr1);
	B* pb4 = dynamic_cast<B*>(ptr2);
	cout << pb3 << endl;
	cout << pb4 << endl << endl;

	return 0;
}

原文鏈接:https://blog.csdn.net/weixin_54183294/article/details/128191955

欄目分類
最近更新