#include<iostream>
#include<assert.h>
using namespace std;
//class 定义类的关键字,stack 是类的名字,{ }中为类的主体
class Stack
{
public:
//成员函数
void Init(int n = 4)
{
array = (int*)malloc(sizeof(int) * n);
if (nullptr == array)
{
perror("malloc申请空间失败");
return;
}
capacity = n;
top = 0;
}
void Push(int x)
{
//扩容
array[top++] = x;
}
int Top()
{
assert(top > 0);
return array[top - 1];
}
void Destroy()
{
free(array);
array = nullptr;
top = capacity = 0;
}
private:
//成员变量 private表示其一下的内容不可修改
int* array;//栈中的数组
size_t capacity;
size_t top;
};//这个分号不可省略
int main()//没有返回值也不可写void!!!
{
Stack st;//类型可以访问 //st是栈对象
st.Init();//通过对象成员函数()调用,编译器会隐式传递this指针(指回当前对象),让成员函数能访问对象的私有成员
st.Push(1);
st.Push(2);//栈顶为2,栈底为1
cout << st.Top() << endl;// << 输出 通过cout输出到控制台
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, 18);
return 0;
}
typedef int STDataType;
typedef struct ListNode
{
int val;
struct ListNode* next;
}LTnode;
#include<iostream>
using namespace std;
struct ListNodeCPP
{
//成员函数
void Init(int x)
{
next = nullptr;
val = x;
}
//成员变量
ListNodeCPP* next;
int val;
};
int main()
{
return 0;
}
定义在类面前的成员函数默认为inline。
三种 | public |
---|---|
访问 | private |
限定符 | protected |
public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能被直接访问,private和protected是一样的。 | |
访问权限作用域从该访问限定符开始的位置到下一个访问限定符的出现时为止,如果后面没有访问 限定符,作用域到}就结束。 | |
class定义成员没有被访问限定符修饰的时候默认为private,struct默认为public。 |
#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)//说明Init不是一个全局函数,是类的成员函数
{
array = (int*)malloc(sizeof(int) * n);
if (nullptr == array)
{
perror("malloc申请空间失败");
return;
}
capacity = n;
top = 0;
}
int main()
{
Stack st;
st.Init();
return 0;
}
面试题插入:说出声明和定义的区别: 声明就是告诉变量的类型;定义要开空间。
下面给三个例子算一下实例化对象分别有多大?
#include<iostream>
using namespace std;// 计算一下A / B / C实例化的对象是多大?
class A
{
public:
void Print()
{
cout << _ch << endl;
}
private:
char _ch; int _i;
};
class B
{
public:
void Print()
{
//...
}
};
class C
{};
int main()
{
A a;
B b;
C c;
cout << sizeof(a) << endl;
cout << sizeof(b) << endl;
cout << sizeof(c) << endl; //1B和C大小一致,虽然没有成员变量的类,但是它存在就要开空间,给一个字节,纯粹就是为了占位标记
return 0;
}
C++规定不能在实参和形参的位置显示的写this指针(编译时编译器会处理),但是可以在函数体内显示使用this指针。
#include<iostream>
using namespace std;
class Date
{
public:
// void Init(Date* const this, int year, int month, int day)
//所有成员函数都会增加隐含的this指针
void Init(int year, int month, int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
// void Print(Date* const this)
void Print()
{
cout << this->_year << "/" << this->_month << "/" << _day << endl;
}
private:
// 这里只是声明,没有开空间
int _year;
int _month;
int _day;
};
int main()
{
// Date类实例化出对象d1和d2
Date d1;
Date d2;
// d1.Init(&d1, 2024, 3, 31);
d1.Init(2024, 3, 31);
// d1.Print(&d1);
d1.Print();
// d2.Init(&d2, 2024, 7, 5);
d2.Init(2024, 7, 5);
// d2.Print(&d2);
d2.Print();
//不可以写成d2.Print(d2);//但是可以在函数体内写
return 0;
}
下面以两个选择题结束今天的学习 1.这段代码会编译运行结果是()
#include<iostream>
using namespace std;
class A
{
public:
void Print()
{
//cout << this << endl;
cout << "A::Print()" << endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
// mov ecx p
p->Print(); // call 地址
//p->_a = 1;
return 0;
}
2.下面程序编译运行的结果是编译报错为什么?
#include<iostream>
using namespace std;
class A
{
public:
void Print()
{
cout << "A::Print()" << endl;
cout << _a << endl;//_a需要存在对象A里面,这里访问_a是通过this来访问的(相当于解引用)
}
private:
int _a;
};
int main()
{
A* p = nullptr;
// mov ecx p
p->Print(); // call 地址
//调用Print函数传参,把P传给ecx,call位置是地址,地址不存对象P里面,不存在解引用
//不会从对象里面找,地址是在编译的时候就确定的
return 0;
}
指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作