关于类和对象(一)
一.关于类的定义
一.关于类的定义
1.1关于类的格式的定义
首先,我们要知道class在这里为定义类的关键字,Struct为类的名字,在{}里的为类的主体,需要注意定义后面的;不能省略。类中的内容时类的成员,类里面的变量时类的属性或着类的成员变量
在C++中struct升级成了类,它兼容C的用法,struct中可以定义函数,不在需要typedef ListNodecpp就可以代表类型,定义在类的成员函数默认为inline。
#include<iostream>
#include<assert.h>
using namespace std;class Stack
{
public://成员函数void Init(int n = 4){arry = (int*)malloc(sizeof(int) * n);if (arry == nullptr){perror("申请失败\n");return;}capacity = n;top = 0;}void Push(int x){//增容if (top == capacity){size_t newCapacity = 2 * capacity;int* newArry = (int*)realloc(arry, sizeof(int) * newCapacity);if (newArry == nullptr){perror("扩容失败\n");return;}arry = newArry;capacity = newCapacity;}arry[top++] = x;}int Top(){assert(top > 0);return arry[top - 1];}void Destroy(){free(arry);arry = nullptr;top = capacity = 0;}private://成员变量int* arry;size_t capacity;size_t top;
};//要记得这里的;int main()
{Stack st;st.Init();st.Push(2);st.Push(4);cout << st.Top() << endl;st.Destroy();return 0;
}
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day; }
private://一般为了区分成员变量,一般习惯上成员变量会加一个// 特殊的标识符比如_或者m开头int _year;int _month;int _day;
};int main()
{Date d;d.Init(2025, 9, 20);return 0;
}
//C++兼容C中struct的用法
typedef struct ListNodeC
{struct ListNodeC* next;int val;
}LTNode;//不再需要typedef,ListNode CPP就可以代表类型
struct ListNodeC
{void Init(int x){next = nullptr;val = x;}ListNodeC* next;int val;
};
1.2访问限定符
public修饰的成员在类外可以被直接访问,protected和private修饰的成员在类外不能被直接访问。访问权限作用域从该访问限定符出现的位置到下一个访问限定符出现时位置,如果后面没有访问限定符,作用域到 } 即类结束。
class定义成员没有被访问限定符修饰时默认为private ,struct 默认为public
1.3类域
1.类定义了一个新的作用域,类的所有成员都在类的作用域中,在类外定义成员时,需要使用 :: 作用域操作符知名成员属于那个类域。
2.变量的声明和定义的区别就是开不开空间,声明不开空间,定义开空间。
3.类的对象大小进行计算的时候只计算成员变量,不计算成员函数。
#include<iostream>
using namespace std;
class Stack
{
public:
// 成员函数
void Init(int n = 4);
private:
// 成员变量
int* array;
size_t capacity;
size_t top;
};
// 声明和定义分离,需要指定类域
void Stack::Init(int n)
{
array = (int*)malloc(sizeof(int) * n);
if (nullptr == array)
{
perror("malloc申请空间失败");
return;
}
capacity = n;
top = 0;
}
int main()
{
Stack st;
st.Init();
return 0;
}
2.实例化
2.1关于实例化的概念
类我们可以理解为类似于模型的东西,,一个类可以实例化处多个对象,实例化出来的对象占据空间,存储成员变量,类不能存储数据,只有实例化出的对象分配物理内存。
#include<iostream>
using namespace std;
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
// 这⾥只是声明,没有开空间
int _year;
int _month;
int _day;
};
int main()
{
// Date类实例化出对象d1和d2,这里开空间
Date d1;
Date d2;
d1.Init(2024, 3, 31);
d1.Print();
d2.Init(2024, 7, 5);
d2.Print();
return 0;
}
3.关于this指针
1.编译器编译后,类的成员函数默认会在形参的第一个位置,增加一个当前类类型的指针,也就是this指针。
2.类的成员函数中访问成员变量,本质都是通过this指针访问的
3.C++规定不能在形参和实参的位置显示写this指针,但是可以在函数体内显示写this指针。
下面有两道测试题
//下⾯程序编译运⾏结果是()
//A、编译报错 B、运⾏崩溃 C、正常运⾏
class A
{
public:void Print(){cout << "A::Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();//call Printreturn 0;
}
//首先排除A,编译是语法错误,空指针不会报编译错误
// B Print没有存在对象里面,没有解引用,正常运行
//2.下⾯程序编译运⾏结果是()
//A、编译报错 B、运⾏崩溃 C、正常运⾏class A
{
public:void Print(){cout << "A::Print()" << endl;cout << _a << endl;//这里对空指针进行解引用导致程序崩溃}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}