目录
一、面向对象的三大特征
1.1特征
封装
继承
多态
1.2封装
1.2.1封装的概念
该公开的公开化,该私有的就隐藏掉
public:
private:
protected:
保护状态的成员的可访问范围比私有成员大,比公有成员小。能访问私有成员的地方都能访问保护成员。
保护状态的成员扩大的访问范围表现在:基类的保护成员可以在派生类的成员函数中被访问。
记住下图即可:
下图第二行是说,父类中的成员对同在父类中的成员的访问权限
下图第三行是说,子类中的成员对父类中的成员的访问权限
下图第四行是说,外部对父类的访问权限。
(父类其实就是基类,子类其实就是派生类。只不过叫法不一样)
1.2.2封装的作用
便于工作中的分工和分模块,如:加密解密,别人把加密
解密功能封装起来,对外仅提供一个接口,供其他人
使用。再比如让你写一个天气预报的程序,你会天气预报
知识吗,不会吧,那怎么写程序?你会发现先网上有封装
好的程序,这个程序提供了公开接口,你去用就行了。
防止不必要的扩展
就是说有些功能不让你使用,不让你进行扩展。以防止
产生事故。
1.3继承
1.3.1继承的概念
继承就是一种传承,可以把父类型中的数据传承到子类中。子
类除了传承了父类的数据之外,还可以对父类型进行扩展
其实继承就是,子把父类的空间完全复制下来了,并且子
还可以在这这个基础上扩展添加成员。
总的来说,记住下面这几个知识点即可:
注:
1、隐藏是指,其不能从父类中继承下来,其仅仅存在父类中
2、我们一般只用公开继承。私有继承和保护继承一般用不到
公开继承
父类:公开-保护-私有
子类:公开-保护-隐藏
私有继承
父类:公开-保护-私有
子类:私有-私有-隐藏
保护继承
父类:公开-保护-私有
子类:保护-保护-隐藏
1.3.2继承的语法
class A{
/*这是父类型*/
};
class B :public A{
/*B是A的子类型*/
};
class C :public A{
/*C是A的子类型*/
};
class D:public B{
/*D是B的子类型*/
};
1.3.3程序举例
#include <iostream>
using namespace std;
class Animal{
public:
string name;
int age;
void show(){
cout << "this is Animal show()" << endl;
}
};
class Dog:public Animal{
int legs;//增加的成员
public:
void fun(){
//增加的成员
cout << "狗可以看家" << endl;
}
};
int main(){
cout << sizeof(Dog) << endl;
Dog dog;
dog.name="testdog";
dog.show();
dog.fun();
}
1.3.4继承 vs 组合
class Animal{};
class Dog:public{};
Dog dog;/* dog is a Animal,即子类型对象一定可以看成
父类型的对象*/
Animal animal;/*但你不可以说:animal is a Dog,即你
不可以说:父类型对象一定可以看成子类型对象*/
#include <iostream>
using namespace std;
class Animal{
public:
string name;
int age;
void show(){
cout << "this is Animal show()" << endl;
}
};
class Dog:public Animal{
int legs;//增加的成员
public:
void fun(){
//增加的成员
cout << "狗可以看家" << endl;
}
};
class Cat{
/*Cat未继承Animal。但下面这种写法即:组合关系,Cat同样
可以访问Animal成员,同时可以自己扩展成员*/
public:
Animal animal;
int color;//成员扩展
void fun(){
cout << "猫要抓老鼠" << endl;
}
};
int main(){
cout << sizeof(Dog) << endl;
Dog dog;
dog.name="testdog";
dog.show();
dog.fun();
Cat cat;
cat.animal.show();
cat.fun();
}
1.3.5继承方式
公开继承 public
保护继承 protected
私有继承 private
1.3.5.1公开继承
在公开继承下,父类型中的数据是公开的,则到子类中权限是
公开的。父类型中的保护权限的数据到子类中是包含的。父类
中私有的数据到子类中会 隐藏。
程序举例:
#include <iostream>
using namespace std;
class A{
private:
int pri_a;
protected:
int pro_b;
public:
int pub_c;
protected:
int getPri_a(){
/*把私有的pri_a从保护接口中传到子类中*/
pri_a=1000;
return pri_a;
}
};
class B:public A{
public:
void show(){
pro_b=200;
cout << "pro_b=" << pro_b << endl;
/*pri_a=100;私有成员,因此不可以访问。但是想访问也行,
你去A类中开一个接口,把pri_a传过来就可以了:
*/
cout << getPri_a() << endl;
}
};
int main(){
cout << sizeof(B) << endl;//发现B大小和A一样,都是12
B b;
b.pub_c=100;//成功执行
//b.pro_b=100;
/*此语句不可以执行。
pro_b属于保护。注意:保护只能在A类型(本类)中
和B类型中(子类)中使用,不可以在其他区域使用。
但是:你可以使用接口,间接地进行访问,如下语句:*/
b.show();
}
1.3.5.2私有继承
私有类型中,父类型中的公开数据到子类中编程私有的。父类
中的保护数据到子类中成为私有的。父类中私有数据到子类中
会隐藏。
程序举例:
#include <iostream>
using namespace std;
class A{
private:
void showa(){
cout << "shoea()" << endl;
}
protected:
void showb(){
cout << "showb()" << endl;
}
public:
int public_1;
A(int public_1 = 0){
public_1 = 100;
}
void showc(){
cout << "show()" << endl;
}
void show_private(){
//为私有数据提供访问接口
showa();
}
};
class B:private A{
public:
/*为私有数据提供访问接口*/
void show(){
public_1 = 200;//public_1在B中是私有的!!!!!
cout << public_1 << endl;
showc();//访问A的公开成员
showb();//访问A的保护乘员
show_private();//访问A的私有成员,得使用两级接口
}
};
int main(){
B b;
//A a=b;失败,因为是B是A的私有继承
b.show();
}
1.3.5.3保护继承
处于保护状态的成员的可访问范围比私有成员大,比公有成员
小。能访问私有成员的地方都能访问保护成员。
处于保护状态的成员扩大的访问范围表现在:父类的保护成员可
以在子类的成员函数中被访问。
1.3.6继承总结
所谓的继承方式,就是父类能给子类的最大访问权限。
父类中的私有数据,到子类中一定是隐藏的。
二、指针和引用的联系与区别
联系:
引用本质上就是指针。引用完成了指针之前做到的效果,比如:
引用作为参数
myswap(int& a,int& b);(C++函数)
myswap(int* a,int* b);(C语言函数)
引用作为返回值
区别:
1、引用必须进行初始化,指针不需要必须初始化
2、引用是一个别名,引用的大小和引用对象相关;
指着不是别名,指针是一个地址,大小是4个字节。
3、引用一旦初始化,就不能更改引用的对象;
指针随时可以更改指向的对象。
4、有指针的指针 int **
但没有引用的类型 int &&
5、没有引用的指针 int&*这种写法是错的
但有指针的引用 int*&这种写法是对的。相当于二级指针
6、右指针类型的数组 int * data[10];//right
但没有引用类型的数组 int& data[10];//crror
7、但有数组的引用
int data[5];//类型是int data[5]
则其引用为:
int (&data)[5];
这样一来可以直接把数组传到函数中去
程序举例:
#include <iostream>
using namespace std;
void showArr(int (&rdata)[5]){
//把数组传进来
cout << sizeof(rdata) << endl;
}
int main(){
int data[5] = {
9,5,2,7,6};
showArr(data);
}