声明:本文参考了references中列的文章,并加以整理总结。
指针的值是对象的地址,指针可以看做一个存放地址值的整型。
类实例化
- 类实例化的两种方式
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
class C {
public:
C(string s = "", int i = 0, double d = 1.0) {
dataMember1 = s;
dataMember2 = i;
dataMember3 = d;
}
void memberFunction1() {
cout << dataMember1 <<' '<<dataMember2 <<' ' << dataMember3 << endl;
}
void memberFunction2(int i, string s1 = "unknow") {
dataMember2 = i;
cout << i << " received from " << s1 <<endl;
}
protected:
string dataMember1;
int dataMember2;
double dataMember3;
};
int main() {
//创建类实例方法1:直接声明并调用构造函数
C obj1("o1", 11, 111);
obj1.memberFunction1();
//创建类实例方法2:使用指针创建,程序运行完毕后必须释放内存
C *obj2 = new C("O2", 22, 222.0);
obj2->memberFunction1();
obj2->memberFunction2(1000, "C++");
delete obj2;
cout << "The end!" << endl;
return 0;
}
- 创建类对象new与不new的区别
下面是自己总结的一些关于new创建类对象特点:
new创建类对象需要指针接收,一处初始化,多处使用
new创建类对象使用完需delete销毁
new创建对象直接使用堆空间,而局部不用new定义类对象则使用栈空间
new对象指针用途广泛,比如作为函数返回值、函数参数等
频繁调用场合并不适合new,就像new申请和释放内存一样。
Student student(20) ;
//这里student是引用 对象分配在 栈空间中,这里只是我的理解
Student *student = new Student(20);
//这里student是指针,new Student(20)是分配在堆内存空间的
- new对象指针作为函数参数和返回值
class CTest { public: int a; };
class CBest { public: int b; };
CTest* fun(CBest* pBest) {
CTest* pTest = new CTest();
pTest->a = pBest->b;
return pTest;
}
int main() {
CBest* pBest = new CBest();
CTest* pRes= fun(pBest);
if(pBest!=NULL)
delete pBest;
if(pRes!=NULL)
delete pRes ;
return 0;
}
- 必看 (讲了函数参数和多态)
https://www.jianshu.com/p/a75b267325c2
智能指针
https://blog.csdn.net/weixin_42205987/article/details/82946894
#include <memory> //智能指针所在头文件
shared_ptr 是模板类,所以在创建 shared_ptr 时需要指定其指向的类型。shared_ptr 负责在不使用实例时自动释放由它管理的对象,同时它可以自由的共享它指向的对象。
std::shared_ptr大概总结有以下几点:
(1) 智能指针主要的用途就是方便资源的管理,自动释放没有指针引用的资源。
(2) 使用引用计数来标识是否有多余指针指向该资源。(注意,shart_ptr本身指针会占1个引用)。
(3) 在赋值操作中, 原来资源的引用计数会减一,新指向的资源引用计数会加一。
std::shared_ptr<Test> p1(new Test);
std::shared_ptr<Test> p2(new Test);
p1 = p2;
(4) 引用计数加一/减一操作是原子操作,所以线程安全的。
(5) make_shared要优于使用new,make_shared可以一次将需要内存分配好。
// Test 是一个class
std::shared_ptr<Test> p = std::make_shared<Test>(); //推荐
std::shared_ptr<Test> p(new Test);
//std::shared_ptr<Test> p = new Test(); //错误写法!
(6) std::shared_ptr的大小是原始指针的两倍,因为它的内部有一个原始指针指向资源,同时有个指针指向引用计数。
(7) 引用计数是分配在动态分配的,std::shared_ptr支持拷贝,新的指针获可以获取前引用计数个数。
#include <iostream>
#include <string>
#include <memory>
using namespace std;
class Test
{
public:
Test(string name = "initial") //构造函数 initial是默认值
{
this->name_ = name;
cout << this->name_ << " constructor" << endl;
}
~Test() //析构函数
{
cout << this->name_ << " destructor" << endl;
}
string name_; //data member
};
int main()
{
/* 类对象 原生指针构造 */
shared_ptr<Test> pStr1 = make_shared<Test>("BUAA");
// shared_ptr<Test> pStr1(new Test("BUAA")); //another method
cout << (*pStr1).name_ << endl;
cout << pStr1->name_ << endl;
/* use_count()检查引用计数 */
cout << "pStr1 引用计数:" << pStr1.use_count() << endl;
shared_ptr<Test> pStr2 = pStr1;
cout << (*pStr2).name_ << endl;
cout << "pStr1 引用计数:" << pStr1.use_count() << endl;
cout << "pStr2 引用计数:" << pStr2.use_count() << endl;
/* 先new 一个对象,把原始指针传递给shared_ptr的构造函数 */
int *pInt1 = new int(11);
shared_ptr<int> pInt2(pInt1);
/* unique()来检查某个shared_ptr 是否是原始指针唯一拥有者 */
cout << "pInt2.unique() is " << pInt2.unique() << endl; //true 1
/* 用一个shared_ptr对象来初始化另一个shared_ptr实例 */
shared_ptr<int> pInt3(pInt2);
cout << "pInt2.unique() is " << pInt2.unique() << endl; //false 0
cout << "pInt3 引用计数:" << pInt3.use_count() << endl;
cout << "pInt2 引用计数:" << pInt2.use_count() << endl;
return 0;
}
output :
STL容器中存指针,如何delete
必看:https://blog.csdn.net/AC_huang/article/details/29382629
STL中不管是erase或remove都不会释放对象的内存空间,他只是释放了STL里面用来存放这个对象或指针的空间,所以依然需要自己去手动释放,并且释放是有先后顺序的,要先delete 再调用STL里容器对应的erase函数。
vector<Data *> san_dian;
vector<Data *>::iterator it;
for(it = san_dian.begin(); it != san_dian.end(); ) {
delete *it;
it = san_dian.erase(it);
}
references
https://blog.csdn.net/u010039733/article/details/51926966
https://blog.csdn.net/tham_/article/details/44906571
堆空间与栈空间的区别
https://blog.csdn.net/Mormont/article/details/53511441
智能指针
https://blog.csdn.net/weixin_42205987/article/details/82946894
https://blog.csdn.net/thinkerleo1997/article/details/78754919