目录
C++基本程序结构
C++当中的关键字
缺省参数的概念
1.全缺省参数
2.半缺省参数
函数重载的概念
C++中类的定义
类的访问限定符和封装
C++中this指针的用途
C++引用的理解和使用
C++中的内存管理方式
类的6个默认成员函数
构造函数使用
析构函数使用
拷贝构造函数
赋值重载函数
今天给大家肝一波C++的入门基础,帮助大家轻松理解C++编程的实现,基础的学习对于后面深入学习STL库和高阶的数据结构来讲都是非常的重要
面向过程和面向对象初步认识
C是面向过程的:点外卖我们关注的是过程:选单-下单-派送
C++看待外卖系统看待的是每个对象:像商家、骑手、用户等,关注每一个对象要做的事情,比如商家要做的可能包括进货-上架商品-设置价格等
我们先写一个简单程序认识一下如何打印和输出
#include//这里相当于C语言中#include
using namespace std;//std标准命名空间
//必须两个都要包含
void Test01()
{
//输出数据cout<<
cout << "Hello world!!!" << endl;
//打印Hello world!!!
//输入数据cin>>
int a = 0;
cin >> a;//cin相当于scanf
cout << a << endl;
//cout相当于C语言中的printf
//endl相当于\n换行符
}
int main()
{
Test01();
return 0;
}
注意:使用cout标准输出和cin标准输入时,必须包含< iostream >头文件以及std标准命名空间
C++的很多关键字包含了C语言关键字,不需要全部记住,在使用的时候及时查阅文档就可以,这里放一个链接(Reference - C++ Reference (cplusplus.com)可以及时查到C++的很多功能的最新使用
缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参
void TestFunc1(int a = 0)//在括号里写缺省参数
{
cout << a << endl;
}
int main()
{
TestFunc1(); // 没有传参时,使用参数的默认值
TestFunc1(10); // 传参时,使用指定的实参
}
void TestFunc2(int a = 10, int b = 20, int c = 30)
{
cout << "a = " << a << endl;//打印10
cout << "b = " << b << endl;//打印20
cout << "c = " << c << endl;//打印30
}
int main()
{
TestFunc2();
//不传参默认打印10 20 30
}
void TestFunc3(int a, int b = 10, int c = 20)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
}
int main()
{
TestFunc3(5);//打印 5 10 20
TestFunc3(5,20);//打印5 20 20
TestFunc3(5,20,30);//打印5 20 30
//我们传参就使用我们的,不传使用默认的
}
//声明.h
void Func(int a = 10);
//定义.cpp
void Func(int a = 20)
{}
// 缺省参数不能在函数声明和定义中同时出现
注意1. 半缺省参数必须从右往左依次来给出,不能间隔着给
注意2. 缺省参数不能在函数声明和定义中同时出现
C++允许在同一作用域中声明几个功能类似的同名函数,提高复用性
//重载的要求
//1.必须在同一个作用域下
//2.函数名称相同
//3.函数的参数类型不同或者个数、顺序不同
int Add(int left, int right)//函数名都是Add
{
return left + right;
}
double Add(double left, double right)//函数名都是Add,//参数类型不同
{
return left + right;
}
//此时构成函数重载 两个函数可同时存在
int main()
{
Add(1, 2);
Add(2.2, 3.3);
return 0;
}
那么下面两个函数属于函数重载吗?
short Add(short left, short right)
{
return left + right;
}
int Add(short left, short right)
{
return left + right;
}
注意:这里无法构成重载,因为函数的返回值与重载无关
在C++当中,class为定义类的关键字,Date为类的名字,{}中为类的主体,注意类定义结束时后面分号
class Date //class中默认私有
{
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
类的访问限定符:限定类外访问,类里的东西不是说都给你随便用
封装:更严格的管理设计,封装的意思,强制不让你访问我的内部细节
下面我们用一个案例来理解下上面的介绍
//1.类首先数据和方法封装到一起
//2.想给你访问的定义设置成共有
class Date
{
public:
void Print()//类的方法
{
cout << _year << "-" << _month << "-" << _day << endl;
}
//想给你访问的定义设置成公有
void Init(int year=1, int month=1, int day=1)类的方法
{
_year = year;
_month = month;
_day = day;
}
//类的成员 一般情况下,成员数据都是私有或保护的
private:
int _year;
int _month;//不想给你访问的定义成私有
int _day;
};
int main()
{
//类的对象(变量)
Date d1;
d1.Init(2022,5,16);//在对象的后面直接定义
d1.Print();//打印2022-5-16
return 0;
}
这里可以先理解为我们之前的头文件.h函数声明和.cpp文件函数定义都被放到了一起
//注意
//以下注释是编辑器的工作,我们不用做
class Date
{
public:
//void Print(Date* const this)// this 本身不能修改 因为是用const修饰的
//隐含的this指针,不能显示写出来,不能抢编译器饭碗
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
//cout << this->_year << "-" << this->_month
//<< "-" << this->_day << endl;
}
void Init(int year,int month ,int day)
//void Init(Date const *this int year,int month ,int day)
{
_year = year;
//this->_year = year;
_month = month;
//this->_month = month;
_day = day;
//this->_day = day;
}
private:
int _year;//年
int _month;//月
int _day;//日
};
注意在类中是隐含的this指针,不能显示写出来,不能抢编译器饭碗
引用篇内容较多,专门另外写了一篇博客,可以点往学习https://blog.csdn.net/qq_72486849/article/details/125717817?spm=1001.2014.3001.C++
我们知道C语言中动态内存管理方式malloc/calloc/realloc/free等,C++在原有基础上又增加了新的动态内存管理方式
理解new和delete(内置类型)
int main()
{
//申请和释放单个元素的空间,使用new和delete操作符
int* p1 = new int;//new一个int对象
delete p1;//释放
//申请和释放连续的空间,使用 new[]和delete[]
int* p2 = new int[10];//new10个对象 随机值
delete[]p2;//释放
//申请时还可以初始化
int* p3 = new int(10);//new一个int对象,初始化成10
delete p3;//释放
return 0;
}
理解new和delete(自定义类型)
//我们先写一个类 进行调试
class Test
{
public:
Test()
: _data(0)
{
cout << "Test():" << this << endl;
}
~Test()
{
cout << "~Test():" << this << endl;
}
private:
int _data;
};
void Test3()
{
Test* p1 = new Test;//此时会自动调用构造函数初始化
delete p1;//此时会自动调用析构函数清理
}
int main()
{
Test3();
return 0;
}
注意:在申请自定义类型的空间时,new会调用构造函数初始化,delete会调用析构函数
任何一个类在我们不写的情况下,会自动生成下面6个默认成员函数,这里讲下常用的4个默认成员函数
上方案例的Init成员函数我们还可以写成构造函数或初始化列表,一般情况,C++类,都要自己写
//构造函数是完成初始化的
//函数名和类名相同 没有返回值
class Date
{
public:
//构造函数
Date()//不需要写void ,没有返回值
{
_year = 1;
_month = 1;
_day = 1;
}
//构造函数也可以重载
Date(int year,int month,int day)//和上面构成重载
{
_year = year;
_month = month;
_day = day;
}
Date(int year =1, int month=1, int day=1)//3个全缺省
{
_year = year;一般情况下 我们写全缺省的
_month = month;
_day = day;
}
public:
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;//年
int _month;//月
int _day;//日
};
与构造函数相反 ,析构函数不是完成对象的销毁,局部对象销毁工作是由编译器完成的,而对象在销毁时会自动调用析构函数,完成类的一些资源清理工作
//析构函数 没有参数 没有返回值
//有且只有一个
//析构函数不支持重载
//类似我们写数据结构时的Destroy
class Date
{
public:
//构造函数
//一般情况下 我们写全缺省的
Date(int year =1, int month=1, int day=1)
{
cout << "调用构造函数" << endl;
_year = year;
_month = month;
_day = day;
}
//析构函数
//不是销毁对象,是完成资源清理 像 malloc new开辟空间等
~Date()
{
cout << "调用析构函数" << endl;
}
public:
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;//年
int _month;//月
int _day;//日
};
int main()
{
Date d1(2022, 5, 15);//调用构造
d1.Print();//打印2022-5-15 最后1次析构
return 0;
}
构造函数和析构函数,我们不写,编译器都会自动生成,完成资源的初始化和清理工作,并且对于内置类型不做处理,对于自定义类型才会处理
我们自己写的类和内置类型int等传参时不一样,内置类型是直接拷贝字节过去,自定义类型传值传参是要调用拷贝构造的
//拷贝构造
class Date
{
public:
//构造函数初始化
Date(int year =1, int month=1, int day=1)
{
cout << "调用构造函数" << endl;
_year = year;
_month = month;
_day = day;
}
//析构函数清理
~Date()
{
cout << "调用析构函数" << endl;
}
//拷贝构造
// 我们不写,编译器自动生成
//有且只有一个参数,要用引用传参
//Date d2(d1);
Date(const Date& d)//d1传给d,d2就是this
{
cout << "调用拷贝" << endl;
_year = d._year;
_month = d._month;
_day = d._day;
}
public:
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;//年
int _month;//月
int _day;//日
};
int main()
{
Date d2(2022, 5, 16);//调用构造函数
Date d3(d2);//调用拷贝构造 浅拷贝
d2.Print();//打印2022-5-16
d3.Print();//打印2022-5-16 最后两次析构
return 0;
}
注意:拷贝构造函数对于内置类型会完成浅拷贝(值拷贝),对于自定义类型要完成深拷贝
//赋值重载
class Date
{
public:
//构造函数初始化
Date(int year = 1, int month = 1, int day = 1)
{
cout << "调用构造函数" << endl;
_year = year;
_month = month;
_day = day;
}
//析构函数清理
~Date()
{
cout << "调用析构函数" << endl;
}
//赋值重载
//也是自动生成
Date &operator=(const Date& d)//引用
{
cout << "调用赋值重载函数" << endl;
if (this != &d)//取地址
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;//注意返回*this
}
public:
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;//年
int _month;//月
int _day;//日
};
int main()
{
Date d3(2022, 5, 17);//调用构造函数
Date d4;//默认调用构造
d4 = d3;//调用赋值重载
d4.Print();//打印2022-5-17 最后两次析构
return 0;
}
注意:学习这几个函数分为两大方面
1.基本语法特性、函数名、参数、返回值、什么时候调用
2.我们不写编译器自动生成的函数做了些什么事情
希望这篇文章大家有所收获,我们下篇见