一.面向对象概念
C语言:面向过程:机器人行走:考虑 左脚还是右脚 提起多少度 落脚 再迈右脚
C++语言:面向对象语言:行走;
人可以作为一个对象,属性姓名、年龄、身高、体重…行为有走、跑、跳、吃饭、唱歌…..
具有相同性质的对象,我们可以抽象称为类,人属于人类,车属于车类;
面向对象:把数据及对数据的操作方法放在一起,作为一个相互依存的整体。
1.面向过程及面向对象优缺点
面向过程:面向过程分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现按部就班,主要考虑性能,资源使用。不容易复用扩展。
面向对象:建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性。系统更加灵活,性能差。
2.类与对象定义
类是现实世界或思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起。(通俗讲解:类是一种用户自定义的数据类型,用于组织数据和数据操作。类是面向对象程序设计的基础。)
对象是具有类类型的变量。类和对象是面向对象编程技术中的最基本的概念。
3.类与对象的关系
类用来描述对象,对象是类的实体。
4.封装
封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员。
将属性和行为作为一个整体,表示生活中的事物;将属性(变量)与行为(函数)加以权限控制;
目的在于将对象的使用者和设计者分开,以提高软件的可维护性和可修改性。
二.类
1.类格式
class 类名{
属性/行为
};
类中的属性和行为 | 成员 |
属性 | 成员属性、成员变量、数据成员、数据 |
行为 | 成员函数、成员方法 |
2.类权限
权限类型 | 关键字 | |
共有权限 | public | 类内类外都可以访问 |
私有权限 | private | 只能类内访问,不允许子类访问 |
保护权限 | protected | 只能类内访问,可以允许子类访问 |
如果在创建类如下所示,默认情况下是私有的。
#include<iostream>
using namespace std;
class A{
string Name;
void Set_str(string buff)
{
cout<<buff<<endl;
}
void Set_age(int age1)
{
age = age1;
cout<<age<<endl;
}
private:
int age;
protected:
string car;
};
int main()
{
A test;
cout<<sizeof(A)<<endl;
//cout<<test.Set_str("aaa")<<endl;
test.Set_str("aaa");
test.Set_age(111);
}
如果想要控制类中成员变量的读写访问权限,可以将成员属性设置私有。
/#include <stdio.h>标准输入输出头文件
#include <iostream> //i:input o:output stream 流
//命名空间 //设置相关作用域
using namespace std; //cout cin 最后一天
//定义一个类 属性、行为
class Pason{
//访问权限
//公有的
public:
string Name;
//行为 对权限进行控制 读写权限进行控制 读 写 可读可写
void Set_Car(string Car_name)
{
Car = Car_name;
}
string Get_Car(void)
{
return Car;
}
void Set_Lover(string Lover_name)
{
Lover = Lover_name;
}
string Get_Lover(void)
{
return Lover;
}
//将所有成员属性设置为私有,可以实现控制读写权限;
void Set_Age(int age)
{
//对于写权限可以检测数据的有效性;
if(( age >0)&&(age <300))
{
Age = age;
}
else
{
cout <<"你是个老妖精"<<endl;
}
}
//保护的
protected:
string Car;
//私有权限
private:
string Lover;
int Age;
};
int main()
{
//通过蓝图 实例化
Pason xiaomingtaba;
xiaomingtaba.Set_Car("拖拉机");
cout<<xiaomingtaba.Get_Car()<<endl;
xiaomingtaba.Set_Lover("靓女");
cout<<xiaomingtaba.Get_Lover()<<endl;
xiaomingtaba.Set_Age(1000);
return 0;
}
3.实例化对象
class pason;//类
pason obj1,obj2,*obj,obj5[10]; //实例化对象
- 类中非静态成员成员属性分配内存(与普通变量一致),按照定义一次存放。类中成员函数存放在代码区,为类的所有对象共享。sizeof可以计算出来除了代码段以外所有数据大小。
- 类中非静态成员属性分配内存方式与结构体变量一致。
- 在类对象空间并不存储成员函数的指针,而是在链接的时候将调用语句用成员函数的地址代替。
区别 | struct | class |
默认权限 | 公有权限 | 私有(不加关键字默认为私有权限) |
成员函数 | 无 | 有 |
空 | 0,c++中为1 | 1 |
4.问题
如果创建一个类,类中有一个静态变量a。在调用类的时候创建两个对象,那么这两个对象中的a是共用的吗。
答:a是共享的。
三.内联函数
在类的内部声明或者定义的函数。内联函数类似于宏定义,函数调用称为函数体代码。C++编译体在遇到内联函数会用函数体代码替换函数名。
优点:节省函数调用带来的传参,入栈出栈的开销,加快执行速度。
缺点:增加了代码长度。
1.四种内联函数
1.普通函数内联
#include <iostream> //i:input o:output stream 流
//命名空间 //设置相关作用域
using namespace std; //cout cin 最后一天
inline int function()
{
return 1;
}
int main()
{
function();
return 0;
}
2.隐式内联
#include <iostream> //i:input o:output stream 流
//命名空间 //设置相关作用域
using namespace std; //cout cin 最后一天
class pason{
public:
int function()
{
return 1;
}
};
int main()
{
pason a;
a.function();
return 0;
}
3.类外定义,类内声明
#include <iostream> //i:input o:output stream 流
//命名空间 //设置相关作用域
using namespace std; //cout cin 最后一天
class pason{
public:
inline int function();
};
int pason::function()
{
return 1;
}
int main()
{
pason a;
a.function();
return 0;
}
4.追加内联:,表示在类里面没有显式声明,在类外显示定义了内联。
#include <iostream> //i:input o:output stream 流
//命名空间 //设置相关作用域
using namespace std; //cout cin 最后一天
class pason{
public:
int function();
};
inline int pason::function()
{
return 1;
}
int main()
{
pason a;
a.function();
return 0;
}
2.内联注意点
- 使用inline只是给编译器一个建议,适合的处理成内联函数,不适合的情况当做普通函数
-
g++参数:
-O1 提供基础级别的优化
-O2 提供更加高级的代码优化,会占用更长的编译时间
-O3 提供最高级的代码优化
-
通常只有短小的(1-5行)的代码会当做内联函数。
-
内联函数内不能有循环语句和开关语句,会当成普通函数使用
-
内联函数不能递归
3.内联与宏定义区别
- 内联函数在执行调用,宏定义不行
- 编译器会对内联函数的参数类型做安全检验和自动转换,宏定义不行。
- 内联函数可以访问成员变量
- 类内声明同时定义的函数默认为内联函数
四.注意
1.面向对象与面向过程区别
面向过程就是按部就班的一步一步解决问题。
面向对象不是单独解决问题的某一个步骤,而是描述在解决问题中的整个行为。他是把数据和数据操作方法放在一起的整体。
2.类与对象定义
类:共同行为若干对象的整体。是抽象的
对象:具有类类型的变量,用类去描述对象,是具体的。
3.类函数一般类外定义,类内声明。
4.类指针只是一个指向,不占空间
5.在类中定义的变量不一定存储在全局静态存储区,要看在哪实例化。如果在main中实例化,那就存储在栈区。
6.封装的意义:结合性、隐蔽性(API接口)、代码重用性
7.
设计立方体类(Cube)
求出立方体的面积和体积;
分别用全局函数和成员函数判断两个立方体是否相等。
#include<iostream>
using namespace std;
//创建类,实例化一个类保存数据,实例化另一个类参数访问对比
class Cube
{
public:
inline void get_l(const int & a);
inline void get_w(const int & b);
inline void get_h(const int & c);
inline int back_l();
inline int back_w();
inline int back_h();
inline int Judge(Cube & cube);
inline int area();
inline int volume();
private:
int l;
int w;
int h;
};
void Cube::get_l(const int & a)
{
l = a;
}
void Cube::get_w(const int & b)
{
w = b;
}
void Cube::get_h(const int & c)
{
h = c;
}
int Cube::back_l()
{
return l;
}
int Cube::back_w()
{
return w;
}
int Cube::back_h()
{
return h;
}
int Cube::area()
{
return 2 * l + 2 * w + 2 * h;
}
int Cube::volume()
{
return l * w * h;
}
int Cube::Judge(Cube & cube)
{
if((l == cube.back_l()) && (h == cube.back_h()) && (w == cube.back_w()))
{
return 1;
}
else
{
return 0;
}
}
int Judge1(Cube &cube,Cube &cube1)
{
if((cube.back_w() == cube1.back_w())&&(cube.back_l() == cube1.back_l())&&(cube.back_h() == cube1.back_h()))
{
return 1;
}
else
{
return 0;
}
}
int main()
{
Cube cube1;
int a,b;
cube1.get_l(2);
cube1.get_h(3);
cube1.get_w(4);
Cube cube2;
cube2.get_l(2);
cube2.get_h(3);
cube2.get_w(4);
a = cube1.Judge(cube2);
b = Judge1(cube1,cube2);
cout<<"立方体1面积:"<<cube1.area()<<endl;
cout<<"立方体1体积:"<<cube1.volume()<<endl;
cout<<"立方体2面积:"<<cube2.area()<<endl;
cout<<"立方体2体积:"<<cube1.volume()<<endl;
if(a == 1 && b == 1)
{
cout<<"same"<<endl;
}
else
{
cout<<"different"<<endl;
}
}