1.类和对象
1) 一个关于类的实例
#include <iostream>
#include <string>
using namespace std;
const int NAME_LEN = 10;
class CGood // ==》商品的抽象数据类型,不进行内存分配
{
private: // 私有属性
char _name[NAME_LEN];
double _price;
int _amount;
public: // 给外部成员提供公有的方法来访问私有的属性
CGood(char *name, double price, int amount);
~CGood();
void show(); // 打印商品信息
// 给成员变量提供一个getXXX或setXXX的方法(在只想给一个属性赋值,和只想调用该属性的时候)
// 类体内实现的方法,自动定义成inline函数(但是编译并不一定按照inline函数进行编译)
void setName(char * name) { strcpy(_name, name); }
void setPrice(double price) { _price = price; }
void setAmount(int amount) { _amount = amount; }
const char* getName() { return _name; } // 返回值是指向常数的指针,不能通过指针解引用修改指向常量的值
double getPrice() { return _price; }
int getAmounti() { return _amount; }
};
CGood::CGood(char *name, double price, int amount) {}
CGood::~CGood(){}
void CGoods:: show(){}
int main() {
CGood good; // 类实例化之后的对象,进行内存分配
return 0;
}
2) 几点说明
- 对象的内存大小,只和成员变量有关(找占用内存最长的成员变量,以它为内存字节对齐的方式,然后计算对象的大小)
- 直观查询对象占用内存的大小, 使用上图红色下划线的命令输入vs工具,结果如下:
- 最长字节为double类型(_price变量),所以以8字节为对齐方式
- name:占用20个字节,为与8字节对齐,所以添加4个字节: 20+4 = 24
- price: 占用8个字节,刚好对齐:24+8 = 32
- amount: 占用4个字节,需要添加4个字节:32 + 8 = 40;
所以,该对象占用40个字节
2. This指针
3. 构造函数的析构函数
1)使用OOP创建一个数据栈
class SeqStack
{
public:
// 构造函数 SeqStack s1; SeqStack s2(20);
SeqStack(int size = 10) // 是可以带参数的,因此可以提供多个构造函数,叫做构造函数的重载
{
cout << this << " SeqStack()" << endl;
_pstack = new int[size];
_top = -1;
_size = size;
}
// 析构函数
~SeqStack() // 是不带参数的,所有析构函数只能有一个
{
cout << this << " ~SeqStack()" << endl;
delete[]_pstack;
_pstack = nullptr;
}
void push(int val)
{
if (full())
resize();
_pstack[++_top] = val;
}
void pop()
{
if (empty())
return;
--_top;
}
int top()
{
return _pstack[_top];
}
bool empty() { return _top == -1; }
bool full() { return _top == _size - 1; }
private:
int *_pstack; // 动态开辟数组,存储顺序栈的元素
int _top; // 指向栈顶元素的位置
int _size; // 数组扩容的总大小
void resize()
{
int *ptmp = new int[_size * 2];
for (int i = 0; i < _size; ++i)
{
ptmp[i] = _pstack[i];
} // memcpy(ptmp, _pstack, sizeof(int)*_size); realloc
delete[]_pstack;
_pstack = ptmp;
_size *= 2;
}
};
SeqStack gs;
int main()
{
/*
.data
heap
stack
*/
SeqStack *ps = new SeqStack(60); // malloc内存开辟+SeqStack(60)对象构造
ps->push(70);
ps->push(80);
ps->pop();
cout << ps->top() << endl;
delete ps; //先调用ps->~SeqStack()+然后free(ps) delete和free的区别
// 1.开辟内存 2.调用构造函数
SeqStack s;
//s.init(5); // 对象成员变量的初始化操作
for (int i = 0; i < 15; ++i)
{
s.push(rand() % 100);
}
while (!s.empty())
{
cout << s.top() << " ";
s.pop();
}
//s.release(); // 释放对象成员变量占用的外部堆内存(外部资源)
SeqStack s1(50);
//s1.~SeqStack(); // 析构函数调用以后,我们说对象不存在了
s1.push(30); // 堆内存的非法访问了!!!
return 0; //
}