文章目录
- 面向过程和面向对象的概念
- 类的引入
- 访问限定符
- 类的大小
- this指针
面向过程和面向对象的概念
面向过程是一种按照步骤顺序执行的编程方式,而面向对象则是以对象为中心,将数据和操作封装在一起。在面向对象编程中,可以通过定义类和对象来实现数据的抽象和封装,提高代码的可重用性和可维护性。
C语言就是一种面向过程的语言,因而在解决一些较大项目时会显得较为繁琐。
C++则是一款面向对象的语言,因为引入了类的概念。
类的引入
C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。
此外,声明结构体的时候可以省略struct。
typedef int DataType;
struct Stack
{
DataType* _array;
size_t _capacity;
size_t _size;
void Push(const DataType& data)
{
_array[_size] = data;
_size++;
}
void Top()
{
//...
}
};
int main()
{
struct Stack s1;
Stack s2;
s2.Push(1);
}
当然对于上述代码,c++中更喜欢将struct换成关键字class。
class className
{
// 类体:由成员函数和成员变量组成
};
class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。
类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。
类里面的函数也可以像普通函数一样声明和定义分离,不过定义函数时需要加上作用域限定符:
typedef int DataType;
class Stack
{
DataType* _array;
size_t _capacity;
size_t _size;
void Push(const DataType& data);
void Top();
};
void Stack::Push(const DataType& data)
{
{
_array[_size] = data;
_size++;
}
}
访问限定符
- public修饰的成员在类外可以直接被访问
- protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
- 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
- 如果后面没有访问限定符,作用域就到“}”即类结束。
- class的默认访问权限为private,struct为public(因为struct要兼容C)
- 访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别
C++通过类和访问限定符的有机结合实现了封装:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。
类的大小
- 计算类的大小和计算结构体大小的方式一致,忽略成员函数的大小。
- 因为同一个类里面的同一成员函数的地址都是一样的,因此类的成员函数并不存储在类里面。
- 空的类或者只有类的方法而没有类的属性,其用sizeof运算的结果为1。
this指针
C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
typedef int DataType;
struct Stack
{
private:
DataType* _array;
size_t _capacity;
size_t _size;
public:
void Init(size_t capacity = 4)
{
_array = (DataType*)malloc(sizeof(DataType) * capacity);
_capacity = capacity;
_size = 0;
}
void Push(const DataType& data)
{
_array[_size] = data;
_size++;
}
void Top()
{
//...
}
void Print()
{
cout << this << endl;
}
};
int main()
{
Stack s1;
s1.Print();
cout << &s1 << endl;
Stack* ps1 = nullptr;
ps1->Print();
cout << ps1 << endl;
(*ps1).Print();
return 0;
}
观察上述代码的运行结果,我们可以得出以下事实:
- 在调用类的成员函数时,编译器会传一个隐藏的this指针,这个指针不用也不能用户自己实现,但是我们可以调用这个指针。
- 类的成员函数的确不是存储在类中的。(因为我们使用的ps1是空指针却依然调用了成员函数)
- 关于解引用操作只是给计算机的一个建议,至于是否真的需要解引用则由计算机判断。因为我们解引用空指针来调用成员函数却没有报错。