struct Stack
{
int* a;
int top;
int capacity;
};
void StackInit(struct Stack* ps);
void StackPush(struct Stack* ps, int x);
void StackPop(struct Stack* ps);
在C++中是兼容C的,但是C++把struct升级成了类
类里面可以定义成员变量,成员函数
struct Stack
{
void Init()
{
a = nullptr;
top = capacity = 0;
}
void Push(int x)
{
// ...
}
void Pop()
{
// ...
}
int* a;
int top;
int capacity;
};
int main()
{
struct Stack st1;
Stack st2;
st1.Init();
st1.Push(1);
st1.Push(2);
st1.Push(3);
return 0;
}
C++可以这样写,因为ListNode既是类名也是类型
struct ListNode_CPP
{
ListNode_CPP* next;
int val;
};
类的定义
C++中使用calss进行类定义
访问限定符:共有,保护,私有
class Stack
{
public:
void Init()
{
a = 0;
top = capacity = 0;
}
void Push(int x)
{
}
void Pop()
{
}
int Top()
{
return a[top-1];
}
private:
int* a;
int top;
int capacity;
};
int main()
{
Stack st;
st.Init();
st.Push(1);
st.Push(2);
st.Push(3);
st.a = nullptr;//无法访问,因为是私有,类外无法访问,但是类里面的可以访问
return 0;
}
//.h
struct QueueNode
{
QueueNode* next;
int val;
};
class Queue
{
public:
void Init();
void Push(int x);
void Pop();
private:
QueueNode* head;
QueueNode* tail;
};
//.cpp
//类是一个域影响访问,使用::
void Queue::Init()//要说清楚是哪的,不然链接不上,告诉是类里的,去类里面找
{
head = tail = nullptr;
}
void Queue::Push(int x)
{}
void Queue::Pop()
{}
int a;//定义
class Person
{
public:
void Print();//这里是声明
private:
char _arr[20];//这里是声明还是定义 ?
char _age[3];//这里是声明还是定义 ?
int _year;//这里是声明还是定义 ?
};
答案是下面的是声明,那么为什么不是定义
因为此时类并没有进行实例化,也就是说没有进行Person hh;没有进行开辟空间,开辟了空间才能称之为定义
此时我们使用sizeof(Person)验证一下,计算结果为28,既然我们没有实例化,没有实际开辟空间为什么会算出来28这个结果,这就好比我们买房子时,我们的房子并没有建好,但是我们可以看到房子的图纸,根据图纸我们就可以知道我们的房子面积有多大
这里计算类对象的大小也是遵循C中结构体对齐规则的
没有成员变量的对象,给1byte,占位不存储实际数据,标识对象存在
#include<iostream>
using namespace std;
//extern int a;
static int a;
class Person
{
};
int main()
{
cout << sizeof(Person) << endl;
return 0;
}
this指针
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 a;
};
int main()
{
Date d1, d2;
d1.Init(2022,1,11);
d2.Init(2022, 1, 12);
d1.Print();
d2.Print();
return 0;
}
我们运行上面的程序
public:
void Init(Data*const this,int year, int month, int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
void Print(Data*const this)
{
cout <<this->_year<< "-" <<this->_month << "-"<< this->_day <<
endl;
}
这里的this指针编译过程不会显示出来,使用时只可以在函数内部加this- >,在其它地方加错误(实参和形参位置不能显示传递和接收this指针)(可以在成员函数内部使用this指针)
d1.Init(&d1,2022,1,11);//正常使用时不用&d1,下同
d2.Init(&d2,2022,1,12);
d1.Print(&d1);
d2.Print(&d2);
class A {
public:
void Print()
{
cout << "Print()" << endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->Print();
return 0;
}
运行上述代码是可以正常运行的,首先p虽然是空指针,但是我们并没有解引用,其次这里的this指针虽然也是空指针,但是我们并没有使用它进行任何操作,至于为什么怎么调用的Print函数,是通过符号表call函数地址来调用的,下面这种情况就不一样了
// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:
void PrintA()
{
cout<<_a<<endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->PrintA();
return 0;
}
这里运行就会崩溃了,原因是cout<<_a<<endl;这里cout<<this->_a<<endl,用空指针访问
this指针一般存在栈,他是一个形参也可能在寄存器(VS通过ecx寄存器传递,this访问变量提高效率)