第一章:02从c语言到c++
代码运行环境
本节教程所有代码都是在win11系统,Qt 5.12.12版本,mingw编译工具环境编写运行。创建的工程类型为Qt Console Application。
域运算符
域运算符的形式为 :: 。
- :: 运算符可以用于对与局部变量同名的全局变量进行访问
- :: 运算符还可以表示类的成员,具体用法在类中讲解
#include <QCoreApplication>
#include <iostream>
using namespace::std;
//定义了一个全局变量 var
int var = 100;
//本段代码主要讲解域运算符 :: 的使用方法
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int var = 50; //上面得全局变量 var 被下面的局部变量 var给覆盖了。输出结果为50
cout << var << endl;
cout << ::var << endl; //通过::域运算符才能输出全局变量 var
return a.exec();
}
new、delete运算符
new运算符有三种使用方式:new operator;operator new;placement new,本代码只对new operator讨论。operator new 只分配内存;placement new 不分配内存,调用拷贝构造函数。new operator主要做两件事,1.分配内存(malloc);2.调用构造函数。
new运算符可用与创建堆空间,成功则返回首地址,不成功则为异常
语法规则为: 指针变量 = new 数据类型;
语法规则为: 指针变量 = new 数据类型[];
delete运算符主要做的两件事:1.调用析构函数,2.释放内存(free)
delete运算符可用于释放堆空间
语法规则为: delete 指针变量
语法规则为: delete[] 指针变量
#include <QCoreApplication>
#include <iostream>
using namespace::std;
int var = 100;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//创建一个int型数据,并将其地址赋值给指针*p
int *p = new int; //更为一般的理解,分配一个整数类型的空间
//如果要指定分配空间存放的数据,可以这样写
int *test = new int(33);
cout << *test << endl; //结果显示为33
cout << *p <<endl; //打印结果是一个随机的数字
int *pp = new int[10]; //分配连续的十个整数空间
//delete运算符的用法,当删除的是单独的,不需要加[];
//当删除的是连续的空间,需要在delete后跟[]
delete p;
delete[] pp;
return a.exec();
}
重载
重载的前提是在相同的作用域下,两个函数名称相同而参数不同,把这种情况称为重载(overload)
重载的类型有这几种:形参数量不同,形参类型不同,形参顺序不同,形参数量和类型都不同
调用重载函数,编译器通过检查实际参数的个数、类型和顺序来确定响应的函数
重载称为静态的多态,在编译时刻确定函数入口
虚函数称为动态多态,在运行时刻确定函数入口
注意,返回类型不同,参数类型、数量、顺序均相同是错误的,不能称为重载
#include <QCoreApplication>
#include <iostream>
using namespace::std;
void fun(int a, int b) //重载,参数类型不同,在debug模式下查看两个fun函数,地址是不一致的
{
cout << "int" << endl;
}
void fun(double a, double b) //重载,参数类型不同,在debug模式下查看两个fun函数,地址是不一致的
{
cout << "double" << endl;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int aa = 2;
int bb = 2;
fun(aa,bb);
double cc = 2.2;
double dd = 2.2;
fun(cc,dd);
return a.exec();
}
name managling 与 extern “C”
name managling 与 extern "C"作为重载第二部分知识点
name managling这里把它翻译为名字改编,c++为了支持重载而引入的技术
extern "C"是为了实现c与c++混合编程而引入的
extern "C"表示不进行名字改变,按c语言方式解释
下面这段代码编译会出错。加上 extern "C"后函数就不支持重载了,因为不能改名。
#include <QCoreApplication>
#include <iostream>
using namespace::std;
extern "C" void fun(int a, int b) //加上 extern "C"后函数就不支持重载了,因为不能改名
{
cout << "int" << endl;
}
extern "C" void fun(double a, double b) //加上 extern "C"后函数就不支持重载了,因为不能改名
{
cout << "double" << endl;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int aa = 2;
int bb = 2;
fun(aa,bb);
double cc = 2.2;
double dd = 2.2;
fun(cc,dd);
fun(3.3,4.4);
return a.exec();
}
要想让代码能在c语言和c++环境中同时运行,可以这样写。这样写不支持重载
//假设声明了一个头文件,需要让头文件中的函数既能被c语言调用,又能被c++调用
//可以这样写
#include <QCoreApplication>
#include <iostream>
#ifdef __cplusplus
extern "C"
{
#endif
void fun(int a, int b);
void fun2(double a, double b);
#ifdef __cplusplus
}
#endif
带默认参数的函数
在声明或定义函数的时候,可以给形参赋一些默认值。在调用函数时,若没有给出实参,则按指定的默认值进行工作。默认值的定义必须遵循从右到左的顺序,函数调用实参与形参按从左到右进行匹配。
#include <QCoreApplication>
#include <iostream>
using namespace::std;
void fun(int a, int b=10)
{
cout << b << endl;
}
void fun(int a, int b, int c =10); //给出函数的定义
void fun(int a, int b, int c = 6) //在定义中给定了形参,实现就不能再赋值了
{
cout << a + b + c << endl;
}
void fun(double a, double b)
{
cout << "double" << endl;
}
//void fun(int a); //这里声明一个函数,但不实现,调用的时候会报错,当我们调用时查看打印结果
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int aa = 2;
int bb = 2;
fun(aa,bb); //在有 fun(int a, int b, int c =10)和fun(int a, int b)会产生歧义
double cc = 2.2;
double dd = 2.2;
fun(cc,dd);
fun(3.3,4.4);
//fun(3);
return a.exec();
}