#include <iostream>
class Entity {
private:
std::string name;
public:
Entity():name("unknown") {
std::cout << name << " Creat susscifully!" << std::endl;
}
Entity(const std::string& name):name(name){
std::cout << name << " Creat susscifully!" << std::endl;
}
~Entity() { std::cout << "Clear " << name << " object!" << std::endl; }
std::string getname() {
return name;
}
};
int main() {
{
Entity Teru("Miyanaga Teru");
std::cout << Teru.getname() << std::endl;
std::cout << (&Teru)->getname() << std::endl;
}//这里栈上的Teru的作用域结束,编译器自动释放内存
Entity* Ichigo = new Entity("Kurosaki Ichigo");
std::cout << Ichigo->getname() << std::endl;
delete Ichigo;
Entity* Gotei13 = new Entity[13]{ {} ,{"suifeng"},{"gin"}};
delete[] Gotei13;
}
对于一个类Entity,我们可以在栈上创建该类的对象,
Entity Teru("Miyanaga Teru");
Teru即为对象的名称,&Teru访问地址。
在栈上创建的变量由编译器自动管理,使用结束后会自动执行析构函数~Entity释放内存。
在堆上创建对象,需要使用new关键字来申请内存。
Entity* Ichigo = new Entity("Kurosaki Ichigo");
这里new Entity("Kurosaki Ichigo")实际上就是申请的内存的地址。在堆上创建对象我们得到的都是对象的地址,所以用的是指针形式Entity* Ichigo。从地址直接访问该对象中的元素可以使用箭头Ichigo->getname(),或者利用一般的方式(*Ichigo).getname()。
我们在利用new关键字申请内存后,在使用完毕后需要用delete关键字释放内存,此时也同时执行析构函数~Entity。
对于元素组的形式,我们的delete也要做对应改变,比如:
Entity* Gotei13 = new Entity[13]{ {} ,{"suifeng"},{"gin"}};
delete[] Gotei13;
int* a = new int[10];
for (int i = 0; i < 10; i++) {
a[i] = i;
printf("a[%d]: %d\n", i, a[i]);
}
delete[] a;
栈/堆的优劣势
在堆上创建对象我们一般选用智能指针。下为常用的unique_ptr
{
std::unique_ptr<Entity> Kiryu_Miya = std::make_unique<Entity>("Kiryu Miya");//常用的定义方式
std::cout << Kiryu_Miya->getname() << std::endl;//像普通指针一样调用函数
//std::unique_ptr<Entity> miya = Kiryu_Miya;❌ //不支持拷贝
}//在作用域结束后自动释放内存
std::unique_ptr<Entity> Kiryu_Miya(new Entity("Kiryu Miya"));//隐式定义,了解即可,一般不用
如果想拷贝,我们可以选用共享指针shared_ptr
int main() {
std::shared_ptr<Entity> Miya;//创建空的共享指针,引用计数为0
{
std::shared_ptr<Entity> Kiryu = std::make_shared<Entity>("Kiryu Miya");//创建新对象,引用计数为1(仅为共享指针Kiryu持有)
Miya = Kiryu;//Miya和Kiryu共享同一对象,该对象引用计数为2
}//指针Kiryu的作用域结束,被销毁,此时引用计数为1
}指针Miya作用域结束,引用计数为0,释放内存
弱指针weak_ptr可以在不增加引用计数的情况下,可以在不增加引用计数的情况下,观察由共享指针管理的对象。弱指针不能独自存在,它依附于共享指针存在,它不能直接访问地址中的元素,必须通过lock()方法先获取临时的共享指针。弱指针主要作为观察者,用于安全地检查地址中元素是否已被销毁,也可用于打破循环引用等场景。
int main() {
std::weak_ptr<Entity> Miya;\\创建空的弱指针,弱指针指向的地址只能从共享指针中获得
{
std::shared_ptr<Entity> Kiryu = std::make_shared<Entity>("Kiryu Miya");\\创建对象,该对象引用计数为1(被Kiryu持有)
Miya = Kiryu;\\该对象被弱指针Miya观察,引用计数仍为1
std::cout << Miya.expired() << std::endl;\\返回false,该指针指向的内存已未被释放
}Kiryu的作用域结束,对象引用计数为0,释放内存
std::cout << Miya.expired() << std::endl;\\返回true,该指针指向的内存已被释放
}