C++类与对象核心概念详解:定义、访问控制与this指针
C++面向对象编程的核心在于类与对象。本文详细拆解类的引入、定义结构、访问控制权限(public/private/protected)、类对象的大小计算规则,以及解决多对象成员函数调用的this指针机制。
从C语言结构体到C++类
C语言中的结构体仅能包含数据成员(变量),而C++对其进行了扩展,使其能够同时容纳数据成员和函数成员。虽然在语法上struct和class在C++中本质相同,但习惯上使用class来定义类。
struct Date {
int year;
int month;
int day;
void print() {
std::cout << year << "-" << month << "-" << day << std::endl;
}
};类的定义方式
类的定义主要分为两种场景:将声明与实现放在同一个文件中,或采用“头文件声明+源文件实现”的分离模式。
声明与定义全部放在类体中
这种写法简洁,但在类体内直接定义的成员函数会被编译器默认视为内联函数(inline)。这适用于短小简单的函数,以避免函数调用的开销。
声明与定义分离
这是大型项目中的标准做法。头文件(.h)中只放置类声明和成员函数原型,源文件(.cpp)中提供具体实现。
1. 头文件 (Date.h):
class Date {
public:
int year;
int month;
int day;
// 只有声明,没有函数体
void print();
};2. 源文件 (Date.cpp):
#include "Date.h"
#include <iostream>
using namespace std;
// 关键:使用 :: 运算符指定函数所属的类作用域
void Date::print() {
cout << year << "-" << month << "-" << day << endl;
}若漏写 Date::,编译器会将该函数视为全局函数,导致链接错误。
访问限定符与封装
封装通过隐藏内部实现细节,仅暴露必要的接口,从而提高安全性。C++提供了三种访问限定符,其作用域从定义处开始直到下一个限定符出现为止。
1. public(公有)
公有成员在类内和类外均可被直接访问。通常用于定义对外提供的接口方法。
class Date {
public:
int _year; // 公有成员
void init(int y) { _year = y; }
};
// 外部可以合法访问
Date d;
d._year = 2024;2. private 与 protected(私有与保护)
私有成员仅在类内部可见,类外无法直接访问。这强制使用者通过公有成员函数(如 getter/setter)来修改数据,符合封装原则。
class Date {
private:
int _year; // 私有成员
public:
void setYear(int y) { _year = y; }
};
// 以下操作会导致编译错误
Date d;
d._year = 2024; // Error!
3. class 与 struct 的默认差异
虽然语法一致,但若省略访问限定符,class 的默认成员权限是 private,而 struct 的默认权限是 public。
4. this 指针的本质
当多个对象调用同一个非静态成员函数时,函数如何知道当前操作的是哪个对象?答案在于隐藏的 this 指针。
- 类型:
ClassName* const(指向常量的指针,不能改变this的指向)。 - 位置: 作为成员函数的隐式形参存在,存储在栈帧中,不属于对象本身的内存占用。
- 作用: 区分不同对象的数据。
例如上述的 init 函数,实际编译器处理逻辑如下:
void Date::init(Date* const this, int year) {
this->_year = year; // 明确使用this指针指向的对象成员
}类对象的大小计算(类模型)
计算对象大小时遵循C语言结构体的字节对齐规则,但需注意以下特殊情况:
- 成员函数不占空间: 同一类的所有对象共享代码段的函数实体,因此函数代码不计入对象大小。
- 空类大小: 若类中没有成员变量,它仍然占据 1 byte 内存。这是为了标识该对象在内存中的唯一存在(不同于NULL)。
总结
掌握类的定义与访问控制是构建健壮软件的基础。合理使用 private 进行封装,利用 public 提供接口,并理解 this 指针如何处理对象数据的隔离,能有效提升代码的可靠性。以上就是C++类与对象的详细内容,更多关于C++基础学习的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













