C++ 把 结构体“升级成了” 类 ,struct
→ class
//C:
struct ListNode
{
int* _a;
int _size;
int _capacity;
};
//CPP:
struct ListNode2
{
void Init(size_t capacity)
{
_a = (int*)malloc(sizeof(int) * capacity);
if (!_a)
{
perror("malloc fail");
return;
}
_capacity = capacity;
_size = 0;
}
//……
int* _a;
int _size;
int _capacity;
};
class classname
{
类体:由“类的成员”组成
……
};
//CPP:
struct ListNode2
{
void Init(size_t capacity)
{
_a = (int*)malloc(sizeof(int) * capacity);
if (!_a)
{
perror("malloc fail");
return;
}
_capacity = capacity;
_size = 0;
}
//……
int* _a;
int _size;
int _capacity;
};
//.h
class fantasy
{
void Init(int capacity = 4);
//……
int* _a;
int _size;
int _capacity;
};
//.cpp
#include "test.h"
void fantasy::Init(int capacity)//意思是“Init”这个函数是“fantasy”这个类里的成员函数
{
_a = (int*)malloc(sizeof(int) * capacity);
if (!_a)
{
perror("malloc fail");
return;
}
_capacity = capacity;
_size = 0;
}
class DateRB
{
public:
void Init(int year = 0, int month = 0, int day = 0)
{
year = year;
month = month;
day = day;
//这样就很奇怪,到底是谁赋值给谁
}
private:
int year;
int month;
int day;
};
所以,我们建议区别命名:
class DateRB
{
public:
void Init(int year = 0, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
struct
默认class
默认一般:
class MyClass
{
public:
成员函数;
private:
成员变量;
};
类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用
::
作用域操作符指明成员属于哪个类域。
class fantasy//新的作用域
{
void Init(int capacity = 4);
//……
int* _a;
int _size;
int _capacity;
};
void fantasy::Init(int capacity)//指明成员属于哪个类域。
{
_a = (int*)malloc(sizeof(int) * capacity);
if (!_a)
{
perror("malloc fail");
return;
}
_capacity = capacity;
_size = 0;
}
类 → 相当于设计图
类的实例化 → 相当于根据设计图建房
class DateRB
{
public:
void Init(int year = 0, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
DateRB d1;//类的实例化 → 对象
d1.Init();
return 0;
}
class DateRB
{
public:
void Init(int year = 0, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;//4→ 0,1,2,3
int _month;//4→ 4,5,6,7
int _day;//4→ 8,9,10,11
//内存:12byte
};
int main()
{
DateRB d1;//类的实例化
d1.Init();
cout << sizeof(d1) << endl;//output:12
return 0;
}
如上这个例子,sizeof(d1) = 12(byte)
特别的:
// 类中仅有成员函数
class A2 {
public:
void f2() {}
};
// 类中什么都没有---空类
class A3
{};
sizeof(A2) : ?
sizeof(A3) : ?
cout << sizeof(A2) << endl;//output:1
cout << sizeof(A3) << endl;//output:1
这 1 字节 不存储有效数据,只是占位,用来标识 对象被实例化出来。
C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。这个过程编译器自动完成。
void Init(int year = 0, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
//实际上:
void Init(DateRB* this, int year = 0, int month = 0, int day = 0)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
对象 d1
调用函数时,this = &d1
这个地址会传给函数
this
指针 → 隐含的形参,储存在 栈 中定义:DateRB* ptr = nullptr;
class DateRB
{
public:
void Init(int year = 0, int month = 0, int day = 0)
{
_year = year;
_month = month;
_day = day;
}
void func()
{
}
private:
int _year;
int _month;
int _day;
};
int main()
{
DateRB* ptr = nullptr;
ptr->func();//正常运行
ptr->Init(2023, 2, 27);//运行崩溃
(*ptr).func();//正常运行
return 0;
}
nullptr
)传给了 this 指针
,而函数运行过程中 没有对 this 指针解引用操作。ptr->Init(2023, 2, 27);
//运行崩溃void Init(int year = 0, int month = 0, int day = 0)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
显然,Init
函数会对 this 指针
解引用操作,对空指针解引用造成运行崩溃
(*ptr).func();
//正常运行ptr->func();
一样,没有对this 指针解引用'*'
或者 '->'
不一定进行了解引用操作注意:不能这样调用函数
func();
DateRB::func();
CPP:
C:
譬如:取栈顶的元素,可以不通过调用函数的方式而直接访问
cpp Stack st; int top = st.a[st.top]
但是这需要了解栈的底层结构,并且容易出错
END