C与C++的不同点
- C++在struct,union中定义的函数叫成员函数,在class中定义的数据叫数据成员
- C++引入了三个存取权限的关键字:public,protected,private
public:表示数据成员或成员函数是公有的
protected:表示数据是受保护的。不允许其他的程序对其进行直接存取,只能通过他所在的成员函数进行存取
private:表示数据是私有的。与protected一样
成员访问控制 public protected private 类自身 yes yes yes 派生类 yes yes no 其他类 yes no no
注意:private与protected的区别:private的数据是不可被继承的;protected的数据是可以被继承的基类成员访问控制 继承访问控制 在派生类中的访问控制 publilc public public protected protected private 不可访问 publilc protected protected protected protected private 不可访问 publilc private private protected private private 不可访问 - C++中可以把结构体名当做数据类型来使用
struct Student{char name[20];} Student stu;//定义Student类型的变量
- struct关键字定义的数据成员或数据函数缺省时是public;class关键字定义的数据成员或成员函数缺省是private。用union定义的类其所有的成员都是public,这种安排是不可以改变的,它不能使用存取限定符来进行修饰数据权限
- C++中定义参数可以带缺省参数。带缺省参数的函数调用时,如果缺省参数中没有给值,则将缺省值赋值给参数变量
//定义了缺省参数的函数 int fun(int x,int y,int z = 100);
注意:带有缺省值的参数必须放在参数列表的尾部
作用域限定符
代码:
View Code
C++继承
概念:如果B类是由A类继承而来的,那么把B类叫作派生类,A类叫作基类
单继承
单继承语法:
class 派生类名 : 继承方式{ //定义类实体 }
#include<iostream> using namespace std; //基类 class A{ private: int x; int y; public: void setX(int x){ this->x = x; } void setY(int y){ this->y = y; } int getX(){ return x; } int getY(){ return y; } }; //派生类 class B:public A{ private: int z; public: void setZ(int z){ this->z = z; } int getZ(){ return z; } }; int main(){ B b; b.setX(100); b.setY(200); b.setZ(300); cout << b.getX() << " "; cout << b.getY() << " "; cout << b.getZ() << " "; }
示例图:

多继承
多继承语法:
class 派生类名 : 继承方式1 基类名1,继承方式2 基类名2,...{ //定义类实体 };
#include<iostream> using namespace std; //基类1 class A{ protected: int x; public: void setX(int x){ this->x = x; } int getX(){ return x; } }; //基类2 class B{ protected: int y; public: int getY(){ return y; } void setY(int y){ this->y = y; } }; //派生类 class C:public A,public B{ protected: int z; public: void setZ(int z){ this->z = z; } int getZ(){ return z; } }; int main(){ C c; c.setX(100); c.setY(200); c.setZ(300); cout << c.getX() << " "; cout << c.getY() << " "; cout << c.getZ() << " "; }
示例图:

C++重载
重载运算符
概念:对已有的运算符进行重新定义其功能
| 可重载运算符 | 不可重载运算符 |
| 双目运算符(+,-,*,/,%) | .(成员访问运算符) |
| 关系运算符(==,!=,>,<,>=,<=) | .* , ->*(成员指针访问运算符) |
| 逻辑运算符(||,&&,!) | ::(域运算符) |
| 单目运算符(+(正),-(负),*,&) | sizeof |
| 自增(++),自减(--) | ?: |
| 位运算符(|,&,~,^,<<,>>) | #(预处理符号) |
| 赋值运算符(=,+=,-=,*=,/=,&=,|=,...) | |
| 空间申请与释放(new,delete,new[],delete[]) | |
| 其他运算符(()(函数调用),->(成员访问),,(逗号),[](下标)) |
#include <iostream> using namespace std; class Box{ private: int width; int height; public: Box(){ width = 0; height = 0; } Box(int width,int height){ this->width = width; this->height = height; } //重载 + 运算符 Box operator + (const Box &b){ Box box; box.width = this->width + b.width; box.height = this->height + b.height; return box; } //重载输出流 friend ostream &operator<<( ostream &os,const Box &b ){ os << "" << b.width << " height:" << b.height << " "; return os; } //重载输入流 friend istream &operator>>(istream &is,Box &b){ is >> b.width >> b.height; return is; } }; int main(){ Box b1(100,200),b2(300,200); Box b3 = b1+b2; //cin >> b3; cout << b3 << endl; return 0; }
示例图:
重载函数
概念:在一个类中定义多个相同名字的函数,但是参数列表或参数个数不相同的方法
#include <iostream> #include <cstdio> using namespace std; class A{ public: void print(int x){ printf("x=%d ",x); } void print(int x,int y){ printf("x=%d,y=%d ",x,y); } void print(double z){ printf("z=%lf ",z); } }; int main(){ A a; a.print(100); a.print(200,300); a.print(666.6); return 0; }
示例图:

C++成员函数
成员函数的实现:在类定义的内部或外部实现函数。前者称为内联成员函数,后者称为外部成员函数
内部实现:
class A{ private: int x; int y; public:
//定义内联函数 int getX(){return x;} int getY(){return y;} }
外部实现:
class B{ protected: int x; public: void setX(int x); int getX(); } //外部实现 void B::setX(int x){ this->x = x; } int B::getX(){ return this->x; }
C++构造函数与析构函数
概念:构造函数是在建立对象时被调用的;析构函数是在删除对象前被调用的
内部定义:
#include<iostream> using namespace std; class Person{ protected: string name; public: //定义无参构造函数 Person(){ cout << "Person is being created "; name = "Lam"; } //定义有参构造函数 Person(string name){ cout << "Person is being created "; this->name = name; } //定义析构函数 ~Person(){ cout << "Person is being deleted "; } }; int main(){ Person p;//调用无参构造函数 cout << "Next1 "; Person p2("Lam");//调用有参构造函数 cout << "Next2 "; }
外部定义:
#include<iostream> using namespace std; class Person{ protected: string name; public: //定义无参构造函数 Person(); //定义有参构造函数 Person(string name); //定义析构函数 ~Person(); }; Person::Person(){ cout << "Person is being created "; name = "Lam"; } Person::Person(string name){ cout << "Person is being created "; this->name = name; } Person::~Person(){ cout << "Person is being deleted "; } int main(){ Person p;//调用无参构造函数 cout << "Next1 "; Person p2("Lam");//调用有参构造函数 cout << "Next2 "; }
示例图:

调用基(父)类函数
问题:如果想在派生类中使用基类中的函数(这里的函数是指与派生类的函数名相同,但是是功能不同的函数)我们该怎么做呢??
代码:
#include <iostream> using namespace std; /** 派生类类型变量.基类类名::引用的函数(); */ class A{ public: A(){ cout<<"execution function A() "; } void print(){ cout << "print A "; } }; class B:public A{ public: B(){ cout << "execution function B() "; } void print(){ cout << "print B "; } }; int main(){ B b; b.print();//print B ((A)b).print();//print A b.A::print();//print A return 0; }
示例图:

派生类的构造函数实现及执行过程
代码:
#include <iostream> using namespace std; class A{ public: int x; public: A(){ cout<<"execution function A() "; x = 1; } A(int x){ //不会调用无参构造方法A() this->x = x; cout << "x:" << x << endl; } }; class B:public A{ public: int y; public: B(){ //隐式调用父类无参构造函数A() cout << "execution function B() "; y = 1; } B(int x,int y):A(x){//派生类构造函数实现 //这里因为调用了A(x)构造函数,所以不会在隐式调用父类无参构造函数A() this->y = y; cout << "y:" << y << endl; } }; int main(){ cout << "=========A()============ "; A a(200); cout << a.x << endl; cout << "=========B()============ "; B b1; cout << b1.x << endl; cout << b1.y << endl; cout << "=========B(int x,int y)======== "; B b2(100,200);//首先调用B类中的有参构造方法B(int y),然后有参构造方法中隐式调用父类无参构造方法 cout << b2.x << endl; cout << b2.y << endl; return 0; }
示例图:

C++构造函数、析构函数与普通函数的区别
- 构造函数的名字必须与类名相同;析构函数的名字是以波浪号(~)开头加类名组成的。
- 当建立对象时或复制对象时,构造函数会被自动调用;当删除对象前,析构函数会被自动调用。
- 构造函数与构造函数都无返回值。
- 构造函数与析构函数都无法被继承,但是派生类可以调用基类的构造函数
- 构造函数允许重载,有自己的默认参数和初始化列表
- 构造函数不可以是虚函数;析构函数可以是虚函数
- 析构函数不接受任何参数,没有返回值,没有任何值要说明
C++动态对象
概念:在C++ 中提供了动态申请和释放内存空间的两个关键字,分别是new(申请),delete(释放)。
语法:
new 数据类型; delete 指针变量;
注意:new申请内存地址空间成功时,返回对象的指针;若申请失败,则返回空指针(NULL)
代码:
#include <iostream> #define N 100 #define row 4 #define col 6 using namespace std; class A{ public: A(){ cout << "execution function A()" << endl; } ~A(){ cout << "execution function ~A()" << endl; } }; int main(){ //new的使用 //1.基本类型的动态内存分配 double *p = new double; *p = 10000.999; //2.数组的动态内存分配(一维数组) char *c = new char[N]; //3.数组的动态内存分配(4*6的二维数组) int **b = new int*[row]; for(int i = 0; i < N; i++){ b[i] = new int[col]; } //4.对象的动态内存分配 A *a = new A(); A *arr = new A[N]; //delete的使用 //1.释放指针p的内存 delete p; //2.释放指针ch所指向的数组 delete [] c; //3.释放二级指针b所指向的数组 for(int i = 0; i < 4; i++){ delete [] b[i]; } delete[] b; return 0; }
