一、类和数据抽象
面向对象的思想就是将任何事物看作对象,对象有自己的属性和行为,收集这些属性就是数据抽象的任务。
一个空类中包括什么:
class empty
{
public:
empty(); // 无参构造函数
empty(const empty &rh); // 拷贝构造函数
~empty(); // 析构函数
empty & operator=(const empty &rg); // 赋值操作符函数
};
empty e1; // e1:“我很空虚!” 无参构造函数
empty e2(e1); // e2:“我跟你一样空虚!” 拷贝构造函数
empty e3 = e1; // e3:“我也是!我也是!” 赋值操作符
-
用类实现数据的抽象 public:成员可以被类外访问。 private:成员只能在类内访问。 protected:可以被类内和该类的子类访问。 -
构造函数:与类同名的函数,作用:在对象生成的时候,初始化成员数据。 -
析构函数:~ 作用:在对象结束时清理对象的成员数据,释放动态内存分配。
const对象和const成员函数:
//const 修饰变量。声明变量为只读,保护变量以防更改。必须初始化。
const int i = 5;
i = 10;//错误
//const 修饰数组
const int a[9] = {1,2,3 ,4 5,5,9};
//const 修饰指针 1、限定指向空间的值不能更改 2、限定指针不能更改
int i = 5;
int j = 6;
int k = 7;
const int *p = &i; //定义1
作用:声明常量型的变量,修改const类型的数据将引起编译错误。
-
friend对象和friend类 friend 友元。类的friend函数可以访问类的private成员。定义的友元函数需要在类的定义中说明。 友元函数引用的参数就是类的地址,通过类的地址就可以访问类内的成员。 friend void good(Buddy *b);
good(&b);
friend void good(Buddy &b);
good(b);
friend class class2;//类作为友元,可以访问class1中的成员。
-
this 指针 类定义中指向自己的指针,this指针只有在成员函数中才有定义。this指针不能在静态函数中使用 -
动态内存分配 (堆) C 语言:malloc() 首先申请一片连续的内存堆空间,返回指向这片内存空间的指针,需要判断函数返回值是否为NULL。 malloc分配的内存大小至少为size参数所指定的字节数。 int *p = malloc(sizeof(int));
if(P!= NULL){
}
free(p);
C++:new new关键字进行动态内存申请,delete关键字进行内存释放。动态内存由内存==堆==中分配。 类型名 * 指针 = new 类型名;
int * p = new int(size);
delete p;
int * foo;
foo = new int [5]; //返回指向序列的第一个元素的指针,初始化数组大小为1。
foo = new int (1); // 动态分配一个int,初始化为1.
//new关键字初始化
int* pi = new int(1);
float* pf = new float(2.0f);
char* pc = new char('c');
New和malloc的区别:
new关键字是c++的一部分 | malloc是c标准库提供的函数 |
---|
new以具体类型为单位进行内存分配 | malloc以字节为单位进行内存分配 | new在申请单个类型变量时可以进行初始化 | malloc不具备内存初始化的特性 | new返回有类型的指针 | malloc返回无类型的指针 |
二、C++特性 :封装 、继承、多态
封装:实现代码的模块化
封装类的访问类型:public private protected(成员只能被该类的成员函数或派生类的成员函数访问)
继承:实现代码扩展
多态:虚函数,函数重载
通过基类的对象指针或引用访问虚函数
函数重载和函数重写的区别:
函数重载:
//发生在同一个类中,函数名相同,参数列表不一样
函数重写:
//函数重写必须有继承关系
//函数重写的需求:父类的功能无法满足子类的需求
//重写的函数和被重写的函数,函数名和函数参数必须完全一致
//重写的函数和被重写的函数,返回值相同
-
继承 利用一个类生成另一个类的对象。子类获得父类所有成员,此外还有自己的成员。 class father{
};
class son :public father {
};
-
虚拟函数和多态性 虚拟函数: 在父类中定义但不实现,在子类中进行实现。虚拟函数必须加上virtual,通过父类的指针调用实际子类的成员函数。 ? 主要是为了实现一个接口,规范继承。 (通过基类访问派生类定义的函数) **纯虚函数:**virtual void funtion1()=0。函数原型等于0,
虚函数和纯虚函数的区别:
虚函数 | 纯虚函数 |
---|
虚函数必须实现 | 只有声明,没有定义 | 虚函数只能借助于指针或者引用来达到多态的效果 | 派生类仅仅只是继承函数的接口 | 虚函数可以直接使用 | 在子类中实现该函数才可以使用。 |
当基类指针指向一个子类对象,通过这个指针调用子类和基类同名成员函数的时候,基类声明为虚函数「子类不写也可以」就会调子类的这个函数,不声明就会调用基类的。
多态 :通过虚拟函数进行实现,即通过同一个父类的虚拟函数,子类实现不同的功能。
多态体现为父类引用变量可以指向子类对象。
多态的实现依赖于继承,先声明一个父类的实例,分别赋予不同的子类实例。
多态是同一个行为具有多个不同表现形式或形态的能力。
- 模板
利用模板,不仅可以指定全部相关的函数重载。还可以指定全部的类
//继承
#include <iostream>
#include <string>
using namespace std;
class Father {
public:
void set_value(int a, int b) {
height = a;
width = b;
}
protected:
int height;
int width;
};
class Son : public Father {
public:
int area() {
return height * width;
}
};
int main() {
Son s1;
Father F;
s1.set_value(4,5);
cout<<s1.area();
return 0;
}
//虚函数 多态
#include <iostream>
#include <string>
using namespace std;
class Father {
public:
void set_value(int a, int b) {
height = a;
width = b;
}
virtual int area() {
return height * width / 2;
}
protected:
int height;
int width;
};
class Son : public Father {
public:
int area() {
return height * width;
}
};
class Son1 : public Father {
public:
int area() {
return height * width;
}
};
int main() {
Son1 s1;
Father *F = new Son1;
F->set_value(4,5);
cout<<F->area();
return 0;
}
|