8.1-序言
所谓的面向对象其实指的就是我们面向的是能够解决问题的一个具体对象(面向的是一个整体的概念)!
举个栗子:
吃酸辣土豆丝
喊过来一个厨子/去一家饭店/美团找一家
告诉它我们要吃酸辣土豆丝,给它钱
然后送过来就吃上了酸辣土豆丝
8.2-对象
世间万物任何一个具体的事物我们都可以把它当成一个对象(万物皆对象)!
任何对象都会具有两个特征(属性,行为):
- **属性**其实是对**同一类特征的封装和抽象**,最终我们用**变量**来进行描述!
- **行为**其实是对**同一类动作的封装和抽象**,最终我们用**函数**来进行描述!
8.3-类
当我们对同一类具体对象共有属性和行为封装的时候,我们得到的就是一个类,它其实是对具有共有属性和行为的一类具体对象的抽象描述,解决的是频繁创建同一类具体对象所产生的代码冗余的问题!
类的本质:属性 + 行为 + 访问控制权限的聚合体!
属性(变量):
- 对象属性(普通变量)
对象属性就是属于某个具体对象的,必须通过创建具体的对象来使用,每个具体对象的对象属性独立!
- 类的属性(静态变量 static)
类的属性是归属于整个类,所有具体对象共同享有!
静态属性初始化:类的外面通过数据类型 类名::变量名 来进行初始化
- 不变属性(常量属性 const)
- 对象常属性(const)
对象常属性是针对对象来说的不可变属性,一经初始化便不可被修改,构造函数初始化列表来进行初始化!
- 全局常属性(static const)
全局常属性是针对类来说的,针对的是所有对象,一经初始化便不可被修改,类的外面通过数据类型 类名::变量名 来进行初始化!
- 特殊成员(类对象作为成员)
声明一个类的对象作为一个类的成员变量,需要采用构造函数初始化列表来进行初始化!
#include <stdlib.h>
#include <iostream>
using namespace std;
class MyInsideClass
{
public:
MyInsideClass(std::string strName)
{
m_strName = strName;
}
void PrintName()
{
cout << "My name is " << m_strName.c_str() << endl;;
}
private:
std::string m_strName;
};
class MyClass
{
public:
//构造函数: 初始化列表(类对象,对象常属性)
MyClass::MyClass(std::string strConstName) :m_strConstName(strConstName), my("哈哈")//常属性,对于每个对象来说不可修改,但是每个对象可以不一样
{
m_strObjName = "update";
m_strClassName = "update";
//m_strConstName = "update";对象常属性 不可修改
//m_gstrConstName = "update";全局常属性 不可修改
cout << "m_strObjName = " << m_strObjName.c_str() << " ;" << endl;
cout << "m_strClassName = " << m_strObjName.c_str() << " ;" << endl;
cout << "m_strConstName = " << m_strConstName.c_str() << " ;" << endl;
cout << "m_gstrConstName = " << m_gstrConstName.c_str() << " ;" << endl;
my.PrintName();
}
public:
std::string m_strObjName;//对象属性
static std::string m_strClassName;//类的属性
const std::string m_strConstName;//对象常属性
static const std::string m_gstrConstName;//类的常属性
MyInsideClass my;//特殊成员:类的对象
};
//如果声明和实现写在一个文件main.cpp里面,我们必须要将这个初始化写在类的后面
//静态属性 必须在类的外面通过数据类型 类名::变量名 来进行初始化
std::string MyClass::m_strClassName = "init";//可修改
const std::string MyClass::m_gstrConstName = "init";//不可修改
void Test()
{
MyClass myclass1("拉拉");
MyClass myclass2("妥妥");
}
int main(int argc, char* argv[])
{
Test();
system("pause");
return 0;
}
行为(方法):
- 构造函数
构造函数与类同名支持重载,在构建对象时自动被调用,完成一些初始化工作!
类名()
{
}
- 析构函数
析构函数与类同名前面缀有~号,在销毁对象前自动被调用,完成一些释放工作!
~类名()
{
}
- 普通函数
正常声明定义的函数!
- 常量函数
函数名(参数列表) const修饰
被cosnt修饰的函数,内部可以访问成员变量,但是不可修改成员变量!
编译器对const修饰的函数内部处理成了const修饰隐式this指针所指向的对象,那也就是意味着所有通过this指针访问的成员变量不可被修改!
class MyClass
void Func(/默认隐藏了一个this[MyClass this]/) const -> 编译器 -> void Func(const MyClass* this),this被const修饰,所以通过this访问和调用的成员变量不可被修改!
- 类的函数
static 返回值 函数名(参数列表)
static修饰的函数,属于类函数,所有对象都可以访问,静态函数使用类名::方法名来进行使用,静态方法中不可调用和修改对象方法和对象变量!
- 创建对象
- 普通对象
普通对象可以调用const和非const成员函数!
- 常对象
常对象不能调用非const方法,只能调用const方法,调用非const函数时,正常的成员方法存在默认的类名* this默认当前调用对象,但是当前调用对象是const 对象,所以类型不匹配!
#include <stdlib.h>
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass():m_cstrName("ConstName")
{
m_strName = "init";
}
~MyClass()
{
//释放工作
}
void NormalFunc()
{
}
void ConstFunc() const
{
//常函数不可修改对象属性
//m_strName = "";
cout << "m_strName = " << m_strName.c_str() << endl;
cout << "m_cstrName = " << m_cstrName.c_str() << endl;
}
static void StaticFunc()
{
//静态函数不可修改和访问对象属性和方法!
//m_strName = "";
//cout << "m_strName = " << m_strName.c_str() << endl;
}
public:
string m_strName;
const string m_cstrName;
};
void Test()
{
//常对象
const MyClass mcc;
mcc.ConstFunc();
//mcc.NormalFunc();
//普通对象
MyClass mc;
mc.ConstFunc();
mc.NormalFunc();
//静态方法通过类名调用,对象方法需要通过具体对象去调用
MyClass::StaticFunc();
}
int main(int argc, char* argv[])
{
Test();
system("pause");
return 0;
}
控制(权限):
类内部的访问控制权限总共有三种分别是:public,protected,private,默认不写是private!
public:外部可访问 protected:外部仅子类可访问 private:仅内部可访问!
8.4-创建对象
- 栈上创建对象
- 类名 对象名; 通过.来进行访问成员变量和方法!
- const 类名 对象名;常对象
- 堆上创建对象
- new 类名(); 通过new关键字开辟对象内存空间,会调用构造函数!
- delete 销毁对象时,会调用析构函数!
- malloc(sizeof(类名)); 通过malloc关键字开辟内存空间,不会调用构造函数,仅仅只是开辟了对应类的内存空间而已
- free 释放空间时,不会调用析构函数!
- new 类名(); 通过new关键字开辟对象内存空间,会调用构造函数!