C语言中, 结构体就只是结构体, 在C++中, 结构体内不再是结构体, 它代表的是一个类, 它不仅可以定义变量, 也可以定义函数
- 类的定义
声明一个类, 需要使用class关键字或struct关键字修饰类名, 如:
class className{
// 类体:由成员函数和成员变量组成
};
用class声明和struct声明的区别在于成员的默认访问权限不同, class的默认访问权限是private, struct的默认访问权限是public
- - 类的两种定义方式
- 声明和定义全部放在类体中.
需要注意: 成员函数如果在类中定义, 编译器可能会将其当成内联函数处理 - 声明放在.h文件中, 类的定义放在.cpp文件中.
- 类的访问限定符及封装
访问限定符:
- public修饰的成员在类外可以直接被访问
- protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
- 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
注: 访问限定符只在编译时有用, 当数据映射到内存后, 没有任何访问限定符上的区别
封装: 通过访问权限选择性的将其接口提供给外部的用户使用.
作用:
- 保护数据
- 降低耦合
- 降低使用成本
- 类的实例化
用类类型创建对象的过程, 称为类的实例化
- 为什么类需要实例化?
类本身是不占用内存的, 它就相当于一个模子, 而类的实例化就是使用一些资源按着这个模子做出一个实际存在的类出来 - 实例化的类对象需要占用多大的内存?
一个类中不仅可以定义变量, 也可以定义函数, 而不同的类对象之间肯定是不能共用一份数据的, 但是却可以共用这些数据的处理方式, 也就是函数.
因此类的大小仅取决于成员变量的大小, 计算使用内存对齐的方式.
需要注意的是, 类的静态成员变量是被类的所有对象所共享的, 不算入类对象的大小当中 - 类是怎样实现函数被各个对象所共享的?
这就涉及到类的另一个特性了——this指针
- this指针
C++编译器给每个“成员函数“增加了一个隐藏的指针参数, 让该指针指向当前对象(函数运行时调用该函数的对象), 在函数体中所有成员变量的操作, 都是通过该指针去访问. 只不过所有的操作对用户是透明的, 即用户不需要来传递, 编译器自动完成.
this指针的类型:类类型* const
- this指针存在哪里?
this指针存在一般ECX寄存器中(参数个数确定), 通过ECX传递给被调函数; 如果参数个数不确定, this指针所在的参数被压栈后压入堆栈. - this指针可以为空吗?
看情况.比如下面这段代码:
首先定义了一个指向A 类型对象的空指针, 再通过这个指针访问A的成员函数f1,f2.class A { public: void f1() { cout << "i am f1" << endl; } void f2() { cout << "i am f2" << endl; cout << a << endl; } private: int a; }; int main() { A* a = nullptr; a->f1(); a->f2(); return 0; }
访问f1的时候没有对this指针进行解引用, 程序不会报错; 而在访问f2的时候需要通过this指针访问这个对象的成员, 因此程序在打印"i am f2"之后报错.
- const成员
const成员函数是使用const修饰的类成员函数, 它实际上是修饰该成员函数隐含的this指针, 因此, const成员函数不能修改对象的内容
定义:
函数返回值类型 函数名()const{
//函数体
}
根据const成员函数的特性, 在使用时也需要注意:
- const对象不能调用非const成员函数(const对象的内容不能被修改)
- 非const对象可以调用const成员函数(你不想修改我也管不着)
总结: const不能调用非const
- static成员
静态成员变量: 用static修饰的成员变量
静态成员函数: 用static修饰的成员函数
特点:
- 静态成员为所有类对象所共享
- 静态成员变量必须在类外定义, 定义时不添加static关键字
- 类静态成员即可用
类名::静态成员
或者对象.静态成员
来访问 - 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
- 静态成员和类的普通成员一样,也有public、protected、private 3种访问级别,也可以具有返回值
- 友元
友元分为:友元函数和友元类
特点:
- 可以直接访问类的私有成员
- 需要在类中进行声明
- 不能使用const修饰
- 友元关系是单向的
- 友元关系不具有传递性
注: 友元会增加耦合度,不宜多用
- 内部类
内部类: 定义在另一个类的内部的类
特性:
- 内部类是一个独立的类, 它不属于外部类
- 内部类就是外部类的友元类, 内部类可以通过创建外部类对象的方式来访问外部类中的所有成员
- 外部类不是内部类的友元
- 内部类可以定义在外部类的public、protected、private都是可以的
- 注意内部类可以直接访问外部类中的static、枚举成员, 不需要外部类的对象/类名
- sizeof(外部类)=外部类, 和内部类没有任何关系
下面使用代码演示一下内部类的特性:
class A {
const A():x(0) {
}
void const add() {
++count;
}
class B {
void AddA() {
//直接访问A的静态成员
++count;
//通过对象访问
A a;
a.add();
}
};
private:
static int count;
int x;
};
int A::count = 0;