嵌入式软件开发 day26(C++基础)

C++

c 面向过程

c++ 面向对象

后缀名:.cpp

编译:g++

名空间 命名空间管理

using namespace std;	//指定默认的名空间
:: //欲解析运算符,指定名空间的函数
C语言头文件:<stdio.h> <string.h>
C++头文件:<iostream> <cstring> //兼容性强,可以包含除自己本身的C语言的头文件

一、数据的输入与输出

1.cin (输入) – 默认与键盘链接,接受从键盘输入的数据信息。
语法:cin >> 变量;
2.cout(输出) – 默认与屏幕链接,将数据显示到屏幕上。
语法: cout << 变量;

#include <iostream>
using namespace std;
#include<string>
int main()
{
	//整型的输入输出
	int num ;
	cout << "请给整型int赋值:" << endl;
	cin >> num;
	cout << "整型int = " << num << endl;
	//浮点型的输入输出
	double d ;
	cout << "请给浮点型 double 赋值:" << endl;
	cin >> d;
	cout << "浮点型 double = " <<d<< endl;
	//字符型的输入输出
	char ch ;
	cout << "请给字符型 char 赋值:" << endl;
	cin >> ch;
	cout << "字符型 char = " << ch << endl;
	//字符串的输入输出
	string str;
	cout << "请给字符串赋值:" << endl;
	cin >> str;
	cout << "ans = " << str << endl;
	//布尔型输入输出
	bool flag;
	cout << "请给布尔型bool赋值:" << endl;
	cin >> flag;    //输入0为0 其余任何非0数都是1。
	cout << "布尔型 bool = " << flag << endl;

	//实例     输入-520   显示-我爱C++!
	int num1;
	string str1 = "我爱C++!";
	cout << "请输入 520 :" << endl;
	cin >> num1;
	cout << str1 << endl;

	system("pause");
	return 0;
}

二、类和对象

封装:基础 类的抽象过程 描述一类事物的特点

继承:核心 在原有的特点/功能上加上新的特点/功能

多态:延伸 特点:同一条命令作用在不同对象身上显示效果不同

2.1 封装

类:一类事物的统称

对象:某类事物的一个特例/个体

例如:

​ 人可以作为对象,属性有姓名、年龄、身高、体重…,行为有走、跑、跳、吃饭、唱歌…

​ 车也可以作为对象,属性有轮胎、方向盘、车灯…,行为有载人、放音乐、放空调…

​ 具有相同性质的对象,我们可以抽象称为,人属于人类,车属于车类

如何描述一类事物:数据成员(变量)+ 成员方法(函数,宏,inline内联函数[带参宏])

实例化对象

int i;//实例化整型对象i
A a1; //实例化A类型的对象a1

封装的意义

  • 将属性和行为作为一个整体,表现生活中的事物
  • 将属性和行为加以权限控制

封装意义一:

​ 在设计类的时候,属性和行为写在一起,表现事物

封装意义二:

类在设计时,可以把属性和行为放在不同的权限下,加以控制

访问权限有三种:

访问权限有三种:
公共权限  public     类内可以访问  类外可以访问
保护权限  protected  类内可以访问  类外不可以访问
私有权限  private    类内可以访问  类外不可以访问

struct和class区别

在C++中 struct和class唯一的区别就在于 默认的访问权限不同

区别:

  • struct 默认权限为公共
  • class 默认权限为私有

代码演示

#include <iostream>
using namespace std;
//内联函数inline  1类内实现  2用inline关键字类内声明,实现可以写在类外
//public protected private
class Clock
{
public:
	void ShowTime();
	void SetTime(int h,int m,int s);
private:
	int hour;
	int minute;
	int second;
};
void Clock::ShowTime() //::欲解析运算符,指定名空间的函数
{	cout << hour << ":" << minute << ":" << second << endl;  }

void Clock::SetTime(int h,int m,int s)//::欲解析运算符,指定名空间的函数
{	hour = h; minute = m; second = s;	}

int main()
{
	Clock c1;

	c1.ShowTime();

	return 0;
}

对类进行sizeof,得到的是数据成员的大小,不包括成员方法大小

this指针:this指针指向被调用的成员函数所属的对象

this指针是隐含每一个非静态成员函数内的一种指针

this指针不需要定义,直接使用即可

this指针的用途:

  • 当形参和成员变量同名时,可用this指针来区分
  • 在类的非静态成员函数中返回对象本身,可使用return *this

2.2 构造函数

作用:初始化,在一个对象生成的时候被隐式调用,默认有一个系统生成的构造函数,若我们自行实现了构造函数,系统默认的那个不再生成

长相:函数名与类名同名,不需要返回值,可传参,可不传参

构造函数语法类名(){}

  1. 构造函数,没有返回值也不写void
  2. 函数名称与类名相同
  3. 构造函数可以有参数,因此可以发生重载
  4. 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次

代码演示

#include <iostream>
using namespace std;
/*类中的特殊函数*/
/*
构造函数:作用:初始化,在一个对象生成的时候被隐式调用
默认有一个系统生成的构造函数,若我们自行实现了构造函数,系统默认的那个不再生成
长相:函数名与类同名,不需要返回值,可传参(可1个或多个)可无参
构造函数可以同时存在多个
*/

class Clock
{
public:
	Clock(int h=0,int m=0,int s=0);
	void ShowTime();
	void SetTime(int h,int m,int s);
private:
	int hour;
	int minute;
	int second;
};
Clock::Clock(int h,int m,int s)
{	
	cout << "Clock(3*int)" << endl;
	hour = h ; 		
	minute = m;
	second = s;	
}
void Clock::ShowTime()
{	cout << hour << ":" << minute << ":" << second << endl;  }
void Clock::SetTime(int h,int m,int s)
{	hour = h; minute = m; second = s;	}

int main()
{
	Clock c0;
	Clock c1(4);
	Clock c2(14,15);
//	c1.ShowTime();

	return 0;
}

2.3 拷贝构造函数

作用:初始化,在一个对象生成的时候,且用相同类型的已经存在的对象初始化时,调用拷贝构造函数,默认有一个系统生成的拷贝构造函数,若我们自行实现了拷贝构造函数,系统默认的那个不再生成

长相:函数名与类名同名,不需要返回值,参数为常引用(引用通常用来函数传参)

C++中拷贝构造函数调用时机通常有三种情况

  • 使用一个已经创建完毕的对象来初始化一个新对象
  • 值传递的方式给函数参数传值
  • 以值方式返回局部对象

代码演示

#include <iostream>
using namespace std;
/*类中的特殊函数*/
/*
拷贝构造函数:作用:初始化 ,在一个对象生成时,且用相同类型的已存在的对象初始化时调用拷贝构造 
默认有一个系统生成的拷贝构造函数,若我们自行实现了拷贝构造函数,系统默认的那个不再生成
长相:函数名与类同名,无返回值,参数为常引用
*/

class Clock
{
public:
	Clock(int h=0,int m=0,int s=0);
	Clock(const Clock &other);
	~Clock();
	void ShowTime();
	void SetTime(int h,int m,int s);
private:
	int hour;
	int minute;
	int second;
};
Clock::Clock(int h,int m,int s) //构造函数
{	
	cout << "Clock(3*int)" << endl;
	hour = h ; 		
	minute = m;
	second = s;	
}
Clock::Clock(const Clock &other)	//拷贝构造函数
{
	cout << "Clock(&)" << endl;
	hour = other.hour;
	minute = other.minute;
	second = other.second;
}
Clock::~Clock()		//析构函数
{	
	cout << "~Clock()  " << hour <<  endl;
}

void Clock::ShowTime()
{	cout << hour << ":" << minute << ":" << second << endl;  }
void Clock::SetTime(int h,int m,int s)
{	hour = h; minute = m; second = s;	}

int main()
{
	Clock c1(4);
	Clock c2 = c1;
	c2.ShowTime();

	return 0;
}


2.4 析构函数

作用:清理或销毁,在一个对象生命周期即将终止的时候被隐式调用,默认有一个系统生成的析构函数,若我们自行实现了析构函数,系统默认的那个不再生成

长相:函数名与类名同名,前面加~,不需要返回值,不可传参

析构函数语法~类名(){}

  1. 析构函数,没有返回值也不写void
  2. 函数名称与类名相同,在名称前加上符号 ~
  3. 析构函数不可以有参数,因此不可以发生重载
  4. 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次

代码演示

#include <iostream>
using namespace std;
/*类中的特殊函数*/
/*
析构函数:作用:清理或销毁,在一个对象生命周期即将终止时被隐式调用
默认有一个系统生成的析构函数,若我们自行实现析构函数,系统默认的那个不再生成
长相:函数名与类同名,前面加~,不需要返回值,不可传参
*/

class Clock
{
public:
	Clock(int h=0,int m=0,int s=0);
	~Clock();
	void ShowTime();
	void SetTime(int h,int m,int s);
private:
	int hour;
	int minute;
	int second;
};
Clock::Clock(int h,int m,int s)
{	
	cout << "Clock(3*int)" << endl;
	hour = h ; 		
	minute = m;
	second = s;	
}
Clock::~Clock()
{	
	cout << "~Clock()  " << hour <<  endl;
}

void Clock::ShowTime()
{	cout << hour << ":" << minute << ":" << second << endl;  }
void Clock::SetTime(int h,int m,int s)
{	hour = h; minute = m; second = s;	}

int main()
{
	Clock c0;
	{
	Clock c2(14,15);
	}
	Clock c1(4);

	return 0;
}

对象的初始化和清理也是两个非常重要的安全问题

​ 一个对象或者变量没有初始状态,对其使用后果是未知

​ 同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题

c++利用了构造函数析构函数解决上述问题,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。

对象的初始化和清理工作是编译器强制要我们做的事情,因此如果 我们不提供构造和析构,编译器会提供,编译器提供的构造函数和析构函数是空实现

2.2 继承

继承的好处:可以减少重复的代码

2.2.1 继承方式

继承的语法:class 子类 : 继承方式 父类

C++允许一个类继承多个类(多继承语法)

语法:class 子类 :继承方式 父类1 , 继承方式 父类2...

继承方式一共有三种:

  • 公共继承
  • 保护继承
  • 私有继承

在这里插入图片描述

用法class A : public B;

A 类称为子类 或 派生类

B 类称为父类 或 基类

继承的语法:class 子类 : 继承方式 父类

代码演示

#include <iostream>
using namespace std;
/*
父类-子类   基类-派生类
		parent->:	public			protected			private
	public:			public			protected			-
	protected:		protected		protected			-
	private:		private			private				-
*/

class A
{
public:
	A()	{cout << "A()" << endl;}
	~A() {cout << "~A()" << endl;}
	void GetA()	{  cout << "A::GetA() " <<  a << endl;}
protected:
	void Show()	 {	cout << "A::Show()" <<  a << endl;}
private:
	int a;
};

class B : public A
{
public:
	B() {cout << "B()" << endl;}
	~B() {cout << "~B()" << endl;}
	void GetShow() { Show();	}
	void GetA() {  cout << "B::GetA() " << endl;}
};

int main()
{
	B tmp;
	tmp.GetA();

	return 0;
}

问题:父类和子类的构造和析构顺序是谁先谁后?

子类继承父类后,当创建子类对象,也会调用父类的构造函数

总结:继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反

问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢?

总结:

  1. 子类对象可以直接访问到子类中同名成员
  2. 子类对象加作用域可以访问到父类同名成员
  3. 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数

三、动态内存申请

C:malloc free (不会调用构造和析构)

C++:new delete(会调用构造和析构)

1.1 new操作符

​ C++中利用new操作符在堆区开辟数据

​ 堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符 delete

​ 语法:new 数据类型

​ 利用new创建的数据,会返回该数据对应的类型的指针

示例1: 基本语法

#include <iostream>
using namespace std;

int main()
{
	char *p = new char;
	if(p == NULL)
		return -1;

	*p = 'a';
	cout << *p << endl;
	
	delete p;


	return 0;
}

示例2:开辟数组

//堆区开辟数组
int main() {

	int* arr = new int[10];

	for (int i = 0; i < 10; i++)
	{
		arr[i] = i + 100;
	}

	for (int i = 0; i < 10; i++)
	{
		cout << arr[i] << endl;
	}
	//释放数组 delete 后加 []
	delete[] arr;

	system("pause");

	return 0;
}

示例3

#include <iostream>
using namespace std;

class A
{
public:	
	A()	{	str = new char[1]; *str = '\0'	};
	~A() { delete []str;	}
	void Show()	{	cout << str << endl;	}
private:
	char *str;
};

int main()
{
	A a1;
	return 0;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值