c++浅学
浅学一下C++ ,为qt打基础写一个上位机软件来做毕设。
C++编译器
C语言的编译器是gcc,但是C++的编译器是g++,可以通过命令行进行安装
1 | sudo apt-get install g++ |
###hello world
1 |
|
另外的写法
1 |
|
1 |
|
1 | g++ hello.cc -o hello |
cin和cout都是std命名空间下的东西,std::cout和std::cin表示std命名空间下的cout和cin。
命名空间示例:
1 |
|
类和对象
从类中实例化对象分两种方法,一种是从栈中实例化对象,一种是从堆中实例化对象。
1 |
|
构造函数和析构函数
构造函数的特点如下:
(1) 构造函数必须与类名同名;
(2) 可以重载,(重载?新概念,后面学到什么是重载。);
(3) 没有返回类型,即使是 void 也不行。
什么是析构函数?与构造函数相反, 在对象结束其生命周期时系统自动执行析构函数。 实
际上定义类时,编译器会生成一个析构函数。
析构函数的特点如下:
(1) 析构函数的格式为~类名();
(2) 调用时释放内存(资源);
(3) ~类名()不能加参数;
(4) 没有返回值,即使是 void 也不行。
- 构造函数在实例化对象时自动被调用,且在每个对象的生命期仅被调用一次。
- 可以被重载。
- 若程序员没有主动给类定义构造函数,编译器自动给一个缺省的构造函数。
- 一旦程序员定义了一个构造函数,系统将不会再给出缺省构造函数。
- 除了系统缺省的构造函数外,只要构造函数无参或者参数有缺省值, 编译器会认为它就是缺省构造函数。缺省的构造函数同时只能有1个。
缺省构造函数:即无参或参数有缺省值。仅仅是为了构造对象,一种是构造函数不含形参,另一种是构造函数含有形参,并且形参被赋有默认值。
this指针
每个对象都拥有一个 this 指针, this 指针记录对象的内存地址。
在 C++中, this 指针是指向类自身数据的指针, 简单的来说就是指向当前类的当前实例对象。关于类的 this 指针有以下特点:
(1) this 只能在成员函数中使用, 全局函数、静态函数都不能使用 this。 实际上,成员函数默认第一个参数为 T * const this。 也就是一个类里面的成员了函数 int func(int p), func 的原型在编译器看来应该是 int func(T * const this,int p)。
(2) this 在成员函数的开始前构造,在成员函数的结束后清除。
(3) this 指针会因编译器不同而有不同的放置位置。可能是栈,也可能是寄存器,甚至全局变量。
继承
当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。
一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。类派生列表以一个或多个基类命名,形式如下:
1 | class derived-class: access-specifier base-class |
与类的访问修饰限定符一样,继承的方式也有几种。 其中,访问修饰符 access-specifier 是public、 protected 或 private 其中的一个, base-class 是之前定义过的某个类的名称。如果未使用访问修饰符 access-specifier,则默认为 private。
- 公有继承(public):当一个类派生继承公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
- 保护继承(protected): 当一个类派生继承保护基类时,基类的公有和保护成员将成为派生类的保护成员。
- 私有继承(private):当一个类派生继承私有基类时,基类的公有和保护成员将成为派生类的私有成员。
1 |
|
重载
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。
当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。
1 | 1 |
程序中getWeight两个同名函数拥有不同的参数类型,这就是函数重载。
运算符重载的实质就是函数重载或函数多态。运算符重载是一种形式的 C++多态。目的在于让人能够用同名的函数来完成不同的基本操作要重载运算符,需要使用被称为运算符函数的特殊函数形式,运算符函数形式: operatorp(argument-list), operator 后面的’p’为要重载的运
算符符号。 重载运算符的格式如下:
1 | <返回类型说明符> operator <运算符符号>(<参数表>) |
多态
C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数;
形成多态必须具备三个条件:
- 必须存在继承关系;
- 继承关系必须有同名虚函数(其中虚函数是在基类中使用关键字 virtual 声明的函数,在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数);
- 存在基类类型的指针或者引用,通过该指针或引用调用虚函数
虚函数:
是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,
会告诉编译器不要静态链接到该函数。我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。 虚函数声明如下: virtualReturnType FunctionName(Parameter) 虚函数必须实现,如果不实现,编译器将报错
纯虚函数:
若在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。 纯虚函数声明如下:
virtual void funtion1()=0; 纯虚函数一定没有定义,纯虚函数用来规范派生类的行为,即接口。
包含纯虚函数的类是抽象类,抽象类不能定义实例,但可以声明指向实现该抽象类的具体类的指针或引用。
数据封装
封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。
数据封装是一种把数据和操作数据的函数捆绑在一起的机制, 数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制, C++ 通过创建类来支持封装和数据隐藏(public、protected、 private)。