写点什么

c++ 基础——杂谈 2

发布于: 2020 年 09 月 25 日
c++基础——杂谈2



int* a[4] 指针的数组,4个都是存放int类型指针;

int(*b)[4]数组的指针,指向的是int类型包含有5个元素的数组;




const pointer与pointer to const

char strHelloworld[] = {"helloworld"};
char const *pStr1 = "helloworld";
char* const pStr2 = "helloworld";
char const * const pStr3 = "helloworld";

关于const是修饰内容不可变,具体原则:

  1. 看左侧最近的部分;

  2. 如果左侧没有,就看右侧。

通过上述三行代码进行分析:char const *pStr1 = "helloworld";这一行是修饰的是char,那就说明里面的内容不可变,但是存储的指针的指向可以改变;char* const pStr2 = "helloworld";修饰的char*类型的指针,所以指针不可变,但是里面的内容可变; char const * const pStr3 = "helloworld";修饰的是char的内容和char类型的指针,所以都不可以发生变化。


指向指针的指针

一个*代表一次间接访问值;


野指针

下面是对于空指针的判断

int *pA = NULL;
pA = &a;
if (pA!=NULL){
cout<<(&pA)<<endl;
}
pA = NULL;






原始指针的基本运算



指针的左值和右值并不一样

char* cP = &ch;当char* cP = ‘b’;ch的值也会跟着改变。char ch2 = *ch;

椭圆的圈是你最后得到的值。对于一个指针的++操作,只能说是指针得位移操作,并没有赋予具体的值的属性,因此不能作为左值。

从优先级来说,++高于*(取值),这里左值是指,在cp原始空间的往后挪一位的空间,进行初始化操作,可以往里面赋值,填值。


存储区域划分

BSS是没有初始化的变量

GVAR是已经初始化的变量(全局或者是静态的变量)

// demo_test2.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
int a = 0; //全局初始化
int *p1 ; //全局未初始化
int main()
{
int b=1; //栈区变量
char s[] = "abc"; //栈区变量
int *p2 = NULL; //栈区变量
char *p3 = "123456";//p3在栈区,但是内部是在常量区域
static int c = 0;//全局区域
p1 = new int(10);//堆区域
p2 = new int(20);//堆区域
return 0;
}

下面谈一下,资源动态分配--堆(heap)

使用堆进行动态分配内存

1 分配内存块

2 释放之前的内存块



c++资源管理方案--RAII

由于释放的内存块会导致,内存碎片化。用RAII依托栈和析构函数,进行内存管理。


内存泄漏




智能指针

unique_ptr , shared_ptr,weak_ptr,常用的几种智能指针



auto_ptr:

由new expression获得对象,在auto_ptr对象销毁,所管理的对象也会自动被销毁;

但是会发生所有权转移,不小心把它转移另一个智能指针,原来这个指针就不能拥有这个对象。在拷贝过程中直接剥夺指针对于原对象对内存的控制权。

转交给新对象后,将源对象置位nullptr

先把原来的指针置位nullptr,然后新的对象作为tmp保存,让新的指针去指向tmp。



// demo5-8.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string>
#include <iostream>
#include <memory>
using namespace std;
int main()
{
{// 确定auto_ptr失效的范围
// 对int使用
auto_ptr<int> pI(new int(10));
cout << *pI << endl; // 10
// auto_ptr C++ 17中移除 拥有严格对象所有权语义的智能指针
// auto_ptr原理:在拷贝 / 赋值过程中,直接剥夺原对象对内存的控制权,转交给新对象,
// 然后再将原对象指针置为nullptr(早期:NULL)。这种做法也叫管理权转移。
// 他的缺点不言而喻,当我们再次去访问原对象时,程序就会报错,所以auto_ptr可以说实现的不好,
// 很多企业在其库内也是要求不准使用auto_ptr。
auto_ptr<string> languages[5] = {
auto_ptr<string>(new string("C")),
auto_ptr<string>(new string("Java")),
auto_ptr<string>(new string("C++")),
auto_ptr<string>(new string("Python")),
auto_ptr<string>(new string("Rust"))
};
cout << "There are some computer languages here first time: \n";
for (int i = 0; i < 5; ++i)
{
cout << *languages[i] << endl;
}
auto_ptr<string> pC;
pC = languages[2]; // languges[2] loses ownership. 将所有权从languges[2]转让给pC,
//此时languges[2]不再引用该字符串从而变成空指针
cout << "There are some computer languages here second time: \n";
for (int i = 0; i < 2; ++i)
{
cout << *languages[i] << endl;
}
cout << "The winner is " << *pC << endl;
//cout << "There are some computer languages here third time: \n";
//for (int i = 0; i < 5; ++i)
//{
// cout << *languages[i] << endl;
//}
}
return 0;
}



unique_ptr:



// demo5-9.cpp : 定义控制台应用程序的入口点。
//
#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;
}

auto自动检测,推导类型



shared_ptr

引用计数会带来循环引用的问题

导致堆里面无法正常回收,内存泄漏的情况出现



weak_ptr

采用观察者的工作方式,不获取所有权

A可以对B 造成直接的影响

B不能对A产生直接影响



引用

不允许被修改的指针

int x = 1;

int& rx = x;

说明给x起了个小名,把x的地址给了rx

发布于: 2020 年 09 月 25 日阅读数: 39
用户头像

一个孤独的撰写者 2020.07.30 加入

主攻云计算、云安全,c++、python、java均有涉猎

评论

发布
暂无评论
c++基础——杂谈2