C++学习(23)

#学习自用#

union

共用体和结构体相似,但是共用体一次只能占用一个成员的内存,所有成员共用同一地址。

#include<iostream>
using namespace std;
union A
{
	int int_val;
	float float_val;
}a;
int main()
{
	a.float_val = 2.0f;
	cout << a.float_val << endl;
	cout << a.int_val << endl;
	cin.get();	
}

这里a.int_val并不等于2,因为int_val与float_val地址相同,int_val的值其实是float_val在内存中的值。我们可以通过下面这串代码来理解。

#include<iostream>
using namespace std;
int main()
{	
	float b = 2.0;
	int a=*(int*) & b;
	cout << a << endl;


	a = b;
	cout << a << endl;
	cin.get();
}

第一个部分,int a=*(int*) & b ,是取b的地址然后强转为整型指针,再解引用赋值给a,和int_val与float_val的情况类似;而第二个部分,存在隐式转换,实际上是 a=(int )b ;这个部分的结果a=2 。

虚析构函数

虚析构函数并不是在子类中复写基类的析构函数,更像是在基类析构函数的基础上加一个析构函数。

#include<iostream>
using namespace std;
class Base
{
public:
	Base() { cout << "Base construct\n"; }
	~Base() { cout << "Base distroy\n"; }
};
class Derive:public Base
{
public:
	Derive() { cout << "Derive construct\n"; }
	~Derive() { cout << "Derive distroy\n"; }
};
int main()
{
	Base* base = new Base();
	delete base;
	cout << "------------\n";
	Derive* derive = new Derive();
	delete derive;
	cout << "------------\n";
	Base* poly = new Derive();
	delete poly;

	cin.get();
}

在删除poly时并没有调用Derive的析构函数,这里可能会导致内存泄漏,改进方法就是使用虚析构函数。 在基类的虚构函数名前加上virtual即可。只要一个类拥有子类,那么它的析构函数就必须是虚函数否则无法保证安全的扩展这个类。

类型转换

C++中用于类型转换的有static_cast ,reinterpret_cast,dynamic_cast,以及 const_cast,相比于C风格的类型转换,这些语句增加了一些检查功能,各自的使用也有一些限制,下面进行一些简单的介绍。

#include<iostream>
using namespace std;
int main()
{
	double a = 5.25;
	double b = (int)a + 5.3;
	cout << b << endl;
	b = static_cast<int>(a) + 5.3;
	cout << b << endl;
	cout << "------------------\n";

	int c = 1;
	b = *(double*) &c;
	cout << b << endl;
	b = *reinterpret_cast<double*>(&c);
	cout << b << endl;
	cout << "------------------\n";


	cin.get();
}

static_cast只能实现一些基本类型的转换比如float,int之类的,无法实现整型地址向double类型指针的转换,可以看到C风格的转换也可以实现这些功能,如果对性能有要求用C风格是最好的。

#include<iostream>
using namespace std;
class Base
{
public:
	virtual void prt() { cout << "Base type\n"; }
	virtual ~Base() { cout << "Base distroy\n"; }

};
class Derive:public Base
{
public:
	void prt()override  { cout << "Derive type\n"; }
	~Derive()  { cout << "Derive distroy\n"; }
};
int main()
{
	Base* b1 = new Base();//指向父类的父类指针
	Base* b2 = new Derive();//指向子类的父类指针

	Derive* derive = dynamic_cast<Derive*>(b1);
	if (!derive)
		cout << "transmition fail\n";
	else
		derive->prt();
	derive = dynamic_cast<Derive*>(b2);
	if (!derive)
		cout << "transmition fail\n";
	else
		derive->prt();

	delete (b1,b2);//错误的,只删除了b2
	cin.get();
}

dynamic_cast用于有继承关系的转换,转换不成功会返回null,转换不成功的情况:1)两个没有继承关系的类指针之间的转换。2)下行转换(父转子)的情况中,指向父类的父类指针转换为子类指针会失败,而指向子类的父类指针可以转换为子类指针。(如果有多个子类,只能转换成指向的子类)3)上行转换不会失败。4)delete (b1,b2)涉及逗号表达式,逗号表达式的值是右值,所以只删除了b2。如果是delete b1,b2 那么就只删除b1因为逗号的优先级很低,相当于(delete b1),b2 这里b2不起作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值