嵌入式面向对象程序开发(4)

第六课 类型转换

一、static_casr(expr)

1、作用:相关数据类型之间的转换。

(1)类似于C语言的强制转化,保证代码的安全性和正确性。

(2)可用于①相关类型转换;例如整型、实型;②子类转父类;

③ void
*指针与其他类型指针之间的类型转换。

(3)不允许指针之间类型的转换(特例:仅允许void*与其他指针之间的类型转换)。

如:char ch = ‘a’;

char
*pc = &ch;

int
*pt = static_cast<int *>(pc); //指针类char
*->int *

//上方代码是该类错误示例

注:①指针之间的赋值规则:必须是相同指针类型之间赋值(相同步长)。

② void*是万能指针,可以接受任何指针的类型。

2、使用示例:

(1)非指针类型间转换

double b =1.234;

int a = static_cast(b);  //double->int ;

char ch = static_cast(a);  // int->char;

(2)void *指针与其他类型指针之间的转换

int *pa = &a;

void *p = pa;

int *pa 2= static_cast<int
*>§ ; //指针类void *->int *

二、const_ casr(expr)

1、作用:只能用于去除指针和引用的const属性。

注:使用该运算符转换意味着代码设计上存在缺陷。

2、使用示例:

(1)  
去除指针

int a = 1;

const int *pa4 = &a; //pa4指针

int *pa5 = const_cast<int *>(pa4);

//去除const
int *pa4的const属性成为int
*pa4赋左

(2)  
去除引用

int a = 1;

const int &la = a; //la引用

int &la2 = const_cast<int &>(la);

//去除const
int &la的const属性成为int
&la赋左

三、dynamic_cast(expr)

1、作用:运行时类型识别和检查,用于父类子类之间的转换。

四、reinterpret_ casr(expr)

1、作用:任意无关类型之间的转换。

注:①与static_cast区别在于类型之间有无相关性(指针类-步长是否相等)。

②其他类型是允许const赋值给非const类型的。

2、特点:不安全,既不在编译器期也不在运行期进行检查,安全性完全由程序员决定。

3、使用示例:

char *pc = &ch;

int *pa3 = reinterpret_ casr<int
*>(pc); //指针类char *->int *

4、错误示例:

int a = 1;

float c = reinterpret_cast(a);
//int->float

错误原因:int、float为相关的数据类型。

第七课 C++的封装

一、封装

1、封装作用:对外提供接口,屏蔽数据,对内开放数据。

2、C语言的封装:当单一变量无法完成描述需求的时候,封装成函数或结构体类型解决。

问题:即知其接口,又可以直接访问其内部数据。

注:C语言中的封装内容不能是函数(C++中的class可实现),结果可以是函数。

3、C++的封装:class 封装的本质,在于将数据和行为绑定在一起,再通过对象来完成操作。

二、类与对象

1、类的声明:

class
类名称

{

public:

公有成员(外部接口)

private:

私有成员

protected:

保护成员

};

2、权限修饰符:public、private(set/get)、protected

①public后面声明,它们是类与外部的接口,任何外部函数都可以访问公有类型数据和函数。

②private后面声明,只允许本类中的函数访问,而类外部的任何函数都不能访问。

③protected后面声明,与private类似,其差别表现在继承与派生时对派生类的影响不同。

3、class的get/set(在公有中获取私有变量)方法:提供相对安全方式访问成员变量。

4、面向对象编程实例:栈的实现。

5、面向对象的代码结构:使用.h定义类,使用.cpp实现类里的方法,主函数main.cpp。

5、C++栈的实现示例:

Stack.h文件                   Stack.cpp文件(1)

Stack.cpp文件(2)                   main.cpp文件

三、class的构造函数

1、作用:初始化对象的属性。

2、特点:①没有函数返回值;②函数名与类型相同;

③可以重载;④实例(定义)一个对象会自动调用构造函数。

3、种类:

①默认的无参构造函数;②无参构造函数;③类型转换构造函数;

④默认拷贝构造函数;⑤移动拷贝构造函数(、⑥初始化列表)。

4、使用示例:

(1)     
默认的无参构造函数:类里没有任何自定义的构造函数时,会默认生成Test()。

class Test

{

public:

…….

//此处无特意自定义的无参构造函数

//则默认生成一个Test()

private:

int m_num;

int m_age;

string m_name;

char *m_addr;

};

Int main()

{

Test t;

//会调用默认生成的无参构造函数

………

return 0;

}

(2)     
自定义的无参构造函数

class Test

{

public:

Test()  //无参的构造函数

{

m_num = 0;

m_age = 0;

m_name = “jsetc”;

m_addr = new char[20];

cout << “Test” <<
endl;

}

Test(int num,int age,string
name,const char *addr) //重载的构造函数

{

m_num = num;

m_age = age;

m_name = name;

m_addr = new char[20];

strcpy(m_addr,addr);

cout << “Test(int num,int
age, string name,char *addr)” << endl;

}

…….

private:

…….

};

int main()

{

Test
t(1,23,“zhangsan”,“nanjing”);

//以上方重载的函数为例,会自动调用构造函数

cout <<
t.getName() << endl; // getName()在public:中

return 0;

}

(3)     
类型转换构造函数:一个参数的构造函数;

注:存在风险–将其他类型默认转换为类类型;通过explicit修饰构造函数,防止发生默认转换。

class Test

{

public:

………

explicit Test (int num)

//类型转换构造函数:explicit防止发生隐式类型转换

{

cout << " Test int" <<
endl;

m_num = num;

}

…….

private:

…….

};

int main()

{

Test a1{1}; //std::initializer_list

//类中自动生成 Test (std::initializer_list l)

//但当类中有系统自己定义的构造函数时,系统不会默认生成

Test
a2 = {2};

// Test a3 = 3; //错误:将一个整型常量赋值给一个Test类型的对象

//发生了隐式类型转换(存在风险)解决方法:加explicit

……

return 0;

}

(补充): 使用static_cast转换类型,需在public中添加operator。

class Test

{

public:

…….

operator int() 
//类类型转换运算符重载:支持static_cast()

{

return m_num;

}

operator string() //支持static_cast()

{

return m_name;

}

…….

};

int main()

{

Test a4;

int num = static_cast(a4);

cout << num << endl;

string name = static_cast(a4);

………

return 0;

}

(4)  默认的拷贝构造函数:当类中无拷贝构造函数时,系统会默认生成一个拷贝构造函数: Test (const Test &a);

(5)  自定义拷贝构造函数(拷贝!= 赋值)

class Test

{

public:

…….

A(const A &other) //自定义的拷贝函数

{

m_num = other.m_num;

cout << “A cope A”
<< endl;

}

private:

…….

};

int main()

{

A
a1(a);//调用拷贝构造函数A(const A &other)

A
a3 = a;//调用拷贝构造函数A(const A &other)

//A
a2;  a2 = a;//赋值运算符
!= 拷贝

return 0;

}

(补充):赋值运算符重载(即上方的A a2;  a2 = a;)

A& operator =(const A &other) //添加在类中验证赋值运算符 != 拷贝

{

cout << “A operator A” << endl;

m_num = other.m_num;

}

四、class的析构函数

1、作用:释放对象给属性分配的空间。

2、特点:①没有返回值;②不能重载;

③函数名:~类名;④当实例的对象释放空间时被调用。

3、使用示例:

class Test

{

public:

………

~Test() //析构函数,main中使用Test+变量名 会自动调用

{

cout << “~Test” << endl;

delete m_addr; //若无此语句,m_addr所占资源将无法释放

//可释放构造函数中的变量char
m_addr[20]的空间

}

………

private:

………

};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值