1.面向过程和面向对象的区别
1.1 面向过程
面向过程就是所有的方法变量都需要你来定义和实现,所有步骤和函数都需要按部就班的来,先实现步骤1→步骤2→步骤3→步骤4…end。
1.2 面向过程
面向对象则创建了一个实现某种功能特定的类,当我们需要实现这个方法时,我们直接创建该类,直接访问修改类的成员变量和调用类的成员函数即可实现功能。
做个不恰当的比喻:
面向过程当你需要做个蛋炒饭时,你以面向过程的思维,你得自己准备(手搓)+米饭,鸡蛋,香葱,财迷油盐酱醋茶等等等配料等。
面向对象就是直接买个蛋炒饭的料理包或者点一份外卖,直接购买(调用)即可。
2.成员函数和成员对象
C++中结构体(struct) 已经升级成了 类(class),之前 C语言 的struct结构体只能存放内置类型或者自定义类型,而不能存放函数方法,在C++中则可以存放函数方法,后期我们将从struct结构体以后统称为类(struct → class)
2.1C++中手搓单链表
class PNode
{
private://访问限定符
int _val;//类的成员变量
PNode* _next;//类的成员变量
PNode* _tail;//类的成员变量
public://访问限定符
PNode(int x = 0)//类的成员函数
:_val(0)
{
_val = x;
_next = nullptr;
}
PNode*& BuyNode(int x)//类的成员函数
{
PNode* tmp = (PNode*)malloc(sizeof(PNode));
if (nullptr == tmp)
{
perror("buy fail");
exit(-1);
}
tmp->_val = x;
tmp->_next = nullptr;
return tmp;
}
void Push(int x)//类的成员函数
{
PNode* newnode = BuyNode(x);
if (this->_next == nullptr)
{
this->_next = newnode;
_tail = newnode;
}
else
{
_tail->_next = newnode;
_tail = _tail->_next;
}
}
void Print()//类的成员函数
{
PNode* Pr = this;
while (Pr != nullptr)
{
cout << Pr->_val << ' ';
Pr = Pr->_next;
}
}
PNode*& Find(int x);//函数声明
};
PNode*& PNode::Find(int x)//类外函数定义
{
PNode* cur = this;
while (cur != nullptr)
{
if (cur->_val == x)
return cur;
cur = cur->_next;
}
return cur;
}
int main()
{
PNode st(0);//类的实例化,PNode只是代表类型,当用这个类型创建一个具体对象st时,这就是类的实例化
cout << sizeof
for (size_t i = 1; i < 10; i++)
{
st.Push(i);
}
st.Print();
return 0;
}
在上方代码中我们可以发现,C++中 结构体 已经可以放入函数了。
⭐类中的所有成员函数都存在代码段中(公共共享域),所以当计算一个实例化对象的大小时,只会计算该类的成员变量的总大小。
2.1.1 C++ 类的访问限定符
- public 公有:结构体外可以进行访问,如上方的Push、Print函数等
- private 私有:只能在结构体中可以访问,只能通过结构体内部的成员函数进行间接访问,想直接外部访问是不允许的。
- protect 保护:允许派生类访问,派生类是什么后期讲解。
3.类的实例化和this指针
3.1什么是类的实例化
类的实例化是当我们自定义一个类出来时,我们用这个类创建一个有固定命名的变量对象时,这就是类的实例化。
例:
class Date
{
private:
int _year;
int _month;
int _day;
public:
void Print()const//这个const修饰了this指针,表示无法通过this指针修改指向的对象。
{
cout << _year << '/' << _month << '/' << _day << endl;
}
void Init(int y = 1990, int m = 1, int d = 1)
{
this->_year = y;//从这里我们阔以看出隐式传递的this指针。
this->_month = m;//其实我们是不会显性的输入this指针的,编译器会自动在成员变量前添加this指针
this->_day = d;
}
};
int main()
{
int i = 1;//int是整形类 i就是int类的实例化对象
Date a1; //Date是整形类 a1就是Date类的实例化对象
Date.Init();//初始化
return 0;
}
3.1隐式传递的this指针
this指针,是该类对象在调用类成员函数时隐式传递的自己的地址作为第一形参,该形参默认名为this。this指针可以通过const修饰但是因为我们无法看到这个隐式参数,所以我们只能在小括号后使用const修饰this
例:
#include<iostream>
using namespace std;
class Date
{
private:
int _year;
int _month;
int _day;
public:
void Print()const//这个const修饰了this指针,表示无法通过this指针修改指向的对象。
{
cout << _year << '/' << _month << '/' << _day << endl;
}
void Init(int y = 1990, int m = 1, int d = 1)
{
this->_year = y;//从这里我们阔以看出隐式传递的this指针。
this->_month = m;//其实我们是不会显性的输入this指针的,编译器会自动在成员变量前添加this指针
this->_day = d;
}
void fun(int x = 1)
{
cout << "happy new year" << endl;
}
};
int main()
{
Date a1;
Date.Init();//初始化 这里隐式传递了&a1 a1的地址过去。
a1.Print();//这里隐式传递了&a1 a1的地址过去。
return 0;
}
3.3类的空指针问题
3.3.1 关于类空指针的访问问题
#include<iostream>
using namespace std;
class Date
{
private:
int _year;
int _month;
int _day;
public:
void Print()const
{
cout << _year << '/' << _month << '/' << _day << endl;
}
void Init(int y = 1900, int m = 1, int d = 1)
{
this->_year = y;
this->_month = m;
this->_day = d;
}
void fun(int x = 1)
{
cout << "happy new year" << endl;
}
};
int main()
{
Date* pe = nullptr;
//pe这个空指针,是告诉编译器fun这函数在Date类中。
//因为成员函数的地址不在对象中,成员变量在对象中。
pe->fun();//正常运行 ,因为在fun中this即使为nullptr但是并没有访问,所以没报错。
pe->fun1();//运行崩溃 ,在fun1类函数中访问了this指针,this为nullptr所以运行崩溃了
pe->_year;//运行崩溃 ,访问了this指针,this为nullptr所以运行崩溃了
return 0;
}
3.3.2 NULL和nullptr的区别
在C++中NULL已经是int类型了,空指针已经被nullptr替代了。主要原因是在C++中NULL被错误定义了。
4.封装有无的区别
4.1 C++ 有封装
- 数据和函数方法都封装在类中,是整合的(形式上)。
- 能控制访问方式(private public protect),能更安全的保护对象中的数据。
4.2 C语言 无封装
- 数据和方法是分离的。
- 数据的访问自由不受限制,数据安全稳定性不佳。