首页 > 编程语言 >施磊c++基础7

施磊c++基础7

时间:2024-10-22 21:20:26浏览次数:17  
标签:cout int 基础 c++ class cast data public 施磊

C++的四种类型转换

c语言中提供的类型强转

int a = (int)b;

c++提供:

  1. const_cast:去掉常量属性的一个类型转换
	int* p1 = (int*)&a;
	int* p2 = const_cast<int*>(&a);

这两句是一样的,只不过使用第二种,可以保证类型转换是安全的,如果要转换成不符合的类型就会报错。

  1. static_cast:提供编译器认为安全的类型转换
int main()
{
	//1
	int a = 10;
	char b = static_cast<int> (a);
	//2
	int* p = nullptr;
	short* b = static_cast<short*>(p);
	return 0;
}

对于第一种,int转char,编译器认为是安全的,就可以通过
对于第二章,int转成short,编译器认为类型转换无效
那么如果我一定要做这种类型转换呢?那么就是下面的reinterpret_cast

  1. reinterpret_cast:类似c风格的强制类型转换(不安全)
	int *p = nullptr;
	double* b = reinterpret_cast<double*>(p);

即使实际上这种转换并不安全,但也可以编译成功

  1. dynamic_cast:主要用在继承结构中,可以支持RTTI类型识别上下转换

示例代码:

#include<iostream>
using namespace std;

class Base {
public:
	virtual void func() = 0;
};

class Derive1 :public Base
{
public:
	virtual void func() { cout << "Derive -- 1" << endl; }
};

class Derive2 :public Base
{
public:
	virtual void func() { cout << "Derive -- 2" << endl; }
};

void showFunc(Base* p)
{
	p->func();//动态绑定
}
int main()
{
	Derive1  d1;
	Derive2  d2;
	showFunc(&d1);
	showFunc(&d2);
	return 0;
	//Derive -- 1
	//Derive -- 
}

没有问题

但是随着软件开发的需求变更,要增加需求
在Derive2中添加一个函数

class Derive2 :public Base
{
public:
	void func() { cout << "Derive -- 2" << endl; }
	void showFunc{
		cout << "new 2" << endl;
	}
};

现在我要在showFunc中,其他的依旧动态绑定func()函数
而如果是Derive2对象,就要绑定新的showFunc()函数

使用

void showFunc(Base* p)
{
	// dynamic_cast会检查p指针是否指向的是一个Derive2类型的对象。
	//p->vfptr->vftable RTTI信息,如果是Derive2类型的对象
	//转换类型成功---返回Derive2对象的地址给pd2;否则返回nullptr
	Derive2* pd2 = dynamic_cast<Derive2*>(p);

	if (pd2 != nullptr)
	{
		pd2->derive02func();
	}
	else {
		p->func();//动态绑定
	}
}
理解虚基类和虚继承

抽象类(有纯虚函数的类) / 虚基类
virtual

  1. 修饰成员方法是虚函数
  2. 可以修饰继承方式,是虚继承。被继承的类称为虚基类
#include<iostream>
using namespace std;

class A
{
public:
private:
	int ma;
};

class B :virtual public A
{
public:

private:
	int mb;
};

/*
A a:4字节  ma ---》4字节 ma
B b:8字节 ma,mb ---》12字节 vbptr, mb ,ma
*/
int main()
{
	
}

在这里插入图片描述

class A{}; sizeof(A) = 1

class B :public A{};sizeof(B) = 1;

class A {
virtual void fun(){};
};
class B :public A{};sizeof(B) = 4;//vfptr

class A {
virtual void fun(){};
};
class B :virtual public A{};sizeof(B) = 8;//vbptr + vfptr

基类指针指向派生类对象,永远指向的是派生类基类部分数据的起始地址
在这里插入图片描述
由于内存结构*p指向的是派生类基类部分数据的起始地址D8,但是vbptr和mb都还在前面,这时候delete p;就会导致前面的删不掉

菱形继承问题

多重继承:代码的复用 ---- 一派生类有多个基类

菱形继承问题

class D:public B,public C
{
};

在这里插入图片描述
一目了然:D中有两份来自不同父类的ma属性
尽量不要多重继承

实例代码:

#include<iostream>
using namespace std;

class A
{
public:
	A(int data) :ma(data) { cout << "A()" << endl; }
	~A() { cout << "~A()" << endl; }
protected:
	int ma;
};
//===================================================
class B : public A
{
public:
	B(int data) :A(data), mb(data) { cout << "B()" << endl; }
	~B() { cout << "~B()" << endl; }
protected:
	int mb;
};

class C : public A
{
public:
	C(int data) :A(data), mc(data) { cout << "C()" << endl; }
	~C() { cout << "~C()" << endl; }
protected:
	int mc;
};
//===================================================
class D : public B,public C
{
public:
	D(int data):B(data), C(data),md(data) { cout << "D()" << endl; }
	~D() { cout << "~D()" << endl; }
protected:
	int md;
};
int main()
{
	D d(10);
	
}

d的内存布局 ---- 占20字节
在这里插入图片描述
打印结果:
在这里插入图片描述
此时只要在B,C中对A采用虚继承,就可以了。内存结构如下

在这里插入图片描述
注意:此时需要在D中加入A的构造,即使从继承类看,他并没有直接继承A。但是由于B,C都是虚继承,此时A的构造就要定位到D中对A进行构造;

具体如下:

class D : public B,public C
{
public:
	D(int data):A(data),B(data), C(data),md(data) { cout << "D()" << endl; }
	~D() { cout << "~D()" << endl; }
protected:
	int md;
};

标签:cout,int,基础,c++,class,cast,data,public,施磊
From: https://blog.csdn.net/fcopy/article/details/143063467

相关文章

  • JZOJ【基础】素数密码学//注意:后面有彩蛋
    VIP以下是一个C++程序,该程序接受一个合数n作为输入,并尝试将其分解为两个素数的乘积。如果成功找到这样的分解,它将输出所有可能的分解方式;如果找不到,它将输出"error"。#include<bits/stdc++.h>usingnamespacestd;boolisPrime(intnum){if(num<=1){ returnfa......
  • c++时间管理大师
    作者花了一个下午写出来的。c++写的时间管理大师。支持一下。#include<bits/stdc++.h>#include<windows.h>usingnamespacestd;constintpai=250;constintban=pai/2;#defineD1262#defineD2294#defineD3330#defineD4349#defineD5392#defineD6440......