1.类的实例化
class Date
{
public:
void Init(int year,int month,int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;//声明不是定义,声明不开空间,定义开
int _month;
int _day;
};
int main()
{
Date d; //这才是定义,也称对象的实例化
d.Init(2002, 1, 1);
return 0;
}
类是存在于文件系统中,在内存中不占空间,类的本质就是设计图纸,图纸不能住人,建成房子才能住人,所以,类中不能存数据,必须实例化为对象才可以存数据。
1.1 类有多大
但是Init函数存放在哪里?
存放在公共代码区,但可以存放在对象中,但是为什么不存对象中,在每个类中都村一个函数不划算,就比如函数就是小区的篮球场,完全没有必要在每个房子都建造一个篮球场,公共的就可以了。成员变量就相当于卧室。 全员函数也是这样存放的。
注意:没有成员变量,A2大小是1,用来占位,不存储数据,好歹可以表示对象,认为你存在。
2.this指针
2.1 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 main()
{
Date d1; //这才是定义,也称对象的实例化
d1.Init(2002, 1, 1);
Date d2; //这才是定义,也称对象的实例化
d2.Init(2002, 1, 2);
return 0;
}
对于上述类,有这样一个问题:
Date类中由Init与Print两个成员函数,函数体中没有关于不同对象的区分,那当d1调用Init函数时,该函数是如何知道应该设置d1对象,还是d2对象?
C++中使用this指针解决该问题,this指向当前调用的对象,把当前对象的地址传给他了,即:编译器给每个“非静态成员函数”增加了一个隐藏的指针参数,让该指针指向当前对象。编译器会修改成下面的,即:
class Date
{
public:
void Init(Date* const this,int year,int month,int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
}
int main()
{
Date d1;
d1.Init(&d1,2002, 1, 1);
}
但是this不在实参和形参位置显示写,但是在类中可以显示用,所以d1访问的是对象d1中的成员函数,不是类中的。一般不会显示加。
class Date
{
public:
void Init(int year,int month,int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
}
public:
void Init(int year,int month,int day)
{
_year = year;
_month = month;
_day = day;
this->Print(); //和下面不是同一个this,是两个局部变量,值可以一样,但是是两个不同的变量,要是是同一个对象调用就一样,否则。
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
int main()
{
Date d1;
d1.Init(2023,7,20);
d1.Print(); //都是d1调用,this一样
2.2 this指针的经典题目
class A
{
public:
void Print()
{
cout<<"Print"<<endl;
};
int _a;
int main()
{
A* p=nullptr; //声明了一个指向类A对象的指针p,并将其初始化为nullptr,即空指针
p->Print(); //没有解引用,因为函数没有存在对象里面
(*p).Print();//正常运行,Print不在对象里面,不解引用,直接在公共代码段找
p->_a;//没有解引用。但是在老编译器中可能崩溃,没有赋值其他操作
// p->_a=1;//报错
return 0;
}
正常运行
class A
{
public:
void Print()
{
cout<<_a<<endl; //变成this->_a,this是空
};
int _a;
int main()
{
A* p=nullptr;
p->Print(); //运行崩溃
return 0;
}
2.3 this指针的特性
1.this指针本身不可以修改,但是指向的内容可以修改
void print()
{
this++;//错误,本身不可以修改
}
2.3 C和C++实现栈
C++:数据和方法放在一起,优点:体现封装,严格管控。想给你访问的弄成公有,不想给你访问的弄成私有。杜绝随意访问数据,必须调成员函数
.C
#pragma once
#include<stdlib.h>
class Stack
{
public:
//成员函数
void Init();
void push(int x);
int Top();
private:
//成员变量
int* a;
int top;
int capacity;
};
.CPP
#include"Func.h"
void Stack::Init()//告诉编译器Init是Stack的成员函数
{
a = nullptr;
top = capacity = 0;
}
void Stack::push(int x)
{
if (top = capacity)
{
int newcapacity = capacity == 0 ? 4 : capacity * 2;
a = (int*)realloc(a, sizeof(int) * newcapacity);
capacity = newcapacity;
}
a[top++] = x;
}
int Stack::Top()
{
return a[top--];//函数中我知道top指向的是哪个位置
}
.main
#include <iostream>
#include"Func.h"
using namespace std;
int main()
{
Stack st;
st.Init();
st.push(1);
st.push(1);
cout << st.Top() << endl;
return 0;
}
C:数据和方法是分离的,可以任意访问里面的数据,太自由
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void STInit(ST* pst)
{
assert(pst);
pst->a = NULL;
pst->top = 0;
pst->capacity = 0;
}
int main()
{
ST st;
STInit(&st);
STPush(&st,1);
st.a[st.top]
}
2.4 this指针存放的位置
this是一个形参,一般是存放栈帧中
vs下面一般会用ecx寄存器直接传递