C++语法复习笔记-第6章 c++指针

慕课网C++课程

1. 计算机内存

1. 储存层次

在这里插入图片描述

2. 内存单元与地址

在这里插入图片描述
在这里插入图片描述

3. 指针定义

在这里插入图片描述
在这里插入图片描述

2. 左值与右值

1. 数组与指针

在这里插入图片描述

1. 概念

在这里插入图片描述

3. C++中的原始指针

1. 数组指针与指针数组

在这里插入图片描述
在这里插入图片描述

2. const pointer 与 pointer to const

在这里插入图片描述

  • 测试

在这里插入图片描述

  • 数组只是指向了一块字符空间没有自己真实的地址
    在这里插入图片描述
  • pStr1指向了数组指向的字符的地址编译器做了优化

在这里插入图片描述

  • pStr2-指针变量本身的地址为字符数组地址
    在这里插入图片描述
  • pStr3地址指向的字符串内容不能有任何改变
    在这里插入图片描述
  • pStr2指针的内容可以改变但是与pStr1指针指向的内存一致因此虽然pStr1只读但pStr2改变后pStr1指向内容还是发生了改变
    在这里插入图片描述

3. 指向指针的指针

在这里插入图片描述

4.关于野指针

4.1 指向指针的指针

在这里插入图片描述
在这里插入图片描述

4.2 NULL指针

在这里插入图片描述
在这里插入图片描述

4.3 野指针

在这里插入图片描述

5. 指针的基本运算

5.1 & 操作

  • 取地址的值只能做右值取到地址后作为一个空间变量可以赋给一个指针
  • 但是取特定空间的地址操作不能做左值即不能通过取地址操作改变地址
    在这里插入图片描述

5.2 *操作

  • 右值是取指针指向地址空间上的对象值
  • 左值是取指针指向的地址空间可以对地址进行操作
    在这里插入图片描述
    在这里插入图片描述

5.3 ++和–操作

在这里插入图片描述
在这里插入图片描述

  • 不能作为左值只是一个中间的副本没有明确的地址
    在这里插入图片描述
    在这里插入图片描述

5.4 ++++与----运算符

在这里插入图片描述

6. 内存分配

6.1 总览

在这里插入图片描述
在这里插入图片描述

6.2 heap堆

在这里插入图片描述

6.3 分配和回收动态内存的原则

在这里插入图片描述

6.4 资源管理方案–RAII

在这里插入图片描述

6.5 c++中几种变量的对比

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.6 内存泄漏问题

在这里插入图片描述

4 更安全方式使用指针

在这里插入图片描述
在这里插入图片描述

1. 智能指针

auto_ptr

在这里插入图片描述

  • new的对象出了作用域会自动删除
  • 指针设置为空用nullptr,NULL是c语言语法有二意建议用nullptr对指针设空
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

unique_ptr

在这里插入图片描述

#include "stdafx.h"

#include <memory>   // 智能指针
#include <iostream>
using namespace std;
int main()
{
	// 在这个范围之外unique_ptr被释放
	{
		auto i = unique_ptr<int>(new int(10));
		cout << *i << endl;
	}

	// unique_ptr
	auto w = std::make_unique<int>(10);
	cout << *(w.get()) << endl;      // 10
	//auto w2 = w; // 编译错误如果想要把 w 复制给 w2, 是不可以的。
	//  因为复制从语义上来说两个对象将共享同一块内存。

	// unique_ptr 只支持移动语义, 即如下
	auto w2 = std::move(w); // w2 获得内存所有权w 此时等于 nullptr
	cout << ((w.get() != nullptr) ? (*w.get()) : -1) << endl;       // -1
	cout << ((w2.get() != nullptr) ? (*w2.get()) : -1) << endl;   // 10
    return 0;
}

在这里插入图片描述

shared_ptr

  • 需要一个引用计数的信号量控制

在这里插入图片描述
在这里插入图片描述

weak_ptr

  • 解决循环引用的问题
    在这里插入图片描述
  • 用法示例
  • shared_ptr 内部是利用引用计数来实现内存的自动管理
  • 每当复制一个 shared_ptr引用计数会 + 1。当一个 shared_ptr 离开作用域时引用计数会 - 1。
  • 当引用计数为 0 的时候则 delete 内存。
// shared_ptr 
	{
		//shared_ptr 代表的是共享所有权即多个 shared_ptr 可以共享同一块内存。
		auto wA = shared_ptr<int>(new int(20));
		{
			auto wA2 = wA;
			cout << ((wA2.get() != nullptr) ? (*wA2.get()) : -1) << endl;    // 20
			cout << ((wA.get() != nullptr) ? (*wA.get()) : -1) << endl;      // 20
			cout << wA2.use_count() << endl; // 引用计数 2
			cout << wA.use_count() << endl;                                  // 2
		} // WA2出了作用域消亡
		//cout << wA2.use_count() << endl;                                               
		cout << wA.use_count() << endl;                                      // 1
		cout << ((wA.get() != nullptr) ? (*wA.get()) : -1) << endl;          // 20
	}
  • move语法的使用
// move 语法
	//将 wAA 对象 move 给 wAA2意味着 wAA 放弃了对内存的所有权和管理此时 wAA对象等于 nullptr。
	//而 wAA2 获得了对象所有权但因为此时 wAA 已不再持有对象因此 wAA2 的引用计数为 1。
	auto wAA = std::make_shared<int>(30);
	auto wAA2 = std::move(wAA); // 此时 wAA 等于 nullptrwAA2.use_count() 等于 1
	cout << ((wAA.get() != nullptr) ? (*wAA.get()) : -1) << endl;        // -1
	cout << ((wAA2.get() != nullptr) ? (*wAA2.get()) : -1) << endl;      // 30
	cout << wAA.use_count() << endl;                                     // 0
	cout << wAA2.use_count() << endl;   
  • 循环引用问题
// demo5-11.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <string>
#include <iostream>
#include <memory>
using namespace std;

// 具有shared_ptr指针的两个结构体
struct B;
struct A {
	shared_ptr<B> pb;
	~A()
	{
		cout << "~A()" << endl;
	}
};
struct B {
	shared_ptr<A> pa;
	~B()
	{
		cout << "~B()" << endl;
	}
};

// 具有shared_ptr和weak_ptr指针的两个结构体
struct BW;
struct AW
{
	shared_ptr<BW> pb;
	~AW()
	{
		cout << "~AW()" << endl;
	}
};
struct BW
{
	weak_ptr<AW> pa;
	~BW()
	{
		cout << "~BW()" << endl;
	}
};


// pa 和 pb 存在着循环引用根据 shared_ptr 引用计数的原理pa 和 pb 都无法被正常的释放。
// weak_ptr 是为了解决 shared_ptr 双向引用的问题。
void Test()
{
	cout << "Test shared_ptr and shared_ptr:  " << endl;
	shared_ptr<A> tA(new A());       // 1
	shared_ptr<B> tB(new B());       // 1
	cout << tA.use_count() << endl;
	cout << tB.use_count() << endl;
	tA->pb = tB;
	tB->pa = tA;
	cout << tA.use_count() << endl;  // 2
	cout << tB.use_count() << endl;  // 2
}
void Test2()
{
	cout << "Test weak_ptr and shared_ptr:  " << endl;
	shared_ptr<AW> tA(new AW());
	shared_ptr<BW> tB(new BW());
	cout << tA.use_count() << endl;   // 1
	cout << tB.use_count() << endl;   // 1
	tA->pb = tB;
	tB->pa = tA;
	cout << tA.use_count() << endl;   // 1weak_ptr指向tA,不会对tA的引用计数产生影响
	cout << tB.use_count() << endl;   // 2
} // 当作用域结束后Aw计数只有1减一为0后会正常释放Aw消亡后对BW的影响也消除

int main()
{
	Test();
	Test2();

    return 0;
}


在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: c++

“C++语法复习笔记-第6章 c++指针” 的相关文章