简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
1.前言
本篇目的:理解C++之传指针、引用、vector<shared_ptr>用法。
2.概念与用法
C++ 中的指针和引用是两个常用的概念,它们都用于处理变量的别名。尽管它们在使用和语法上有一些区别。
指针(Pointers):
- 指针是一个变量,它存储了一个内存地址,指向另一个变量的位置。
- 指针允许我们通过间接引用间接访问变量。
- 当我们声明一个指针时,它会被初始化为空值(nullptr)或者指向另一个变量的地址。
- 通过使用解引用运算符
*
,我们可以访问指针所指向的变量的值。 - 指针可以进行算术运算,如指针加法和指针减法。
传递指针:
int num = 42; // 声明一个整型变量 num,初始化为 42
int* p; // 声明一个整型指针 pp = # // 将指针 p 指向变量 num 的地址cout << *p << endl; // 解引用指针 p,输出地址所指向的值int anotherNum = 99;
p = &anotherNum; // 修改指针 p 的引用对象为另一个变量cout << *p << endl; // 输出指针 p 所指向的另一个变量的值
传递引用
- 引用是一个与现有变量相关联的别名。
- 引用在声明时必须被初始化,一旦引用被初始化,它就一直引用同一个变量,不能再引用其他变量。
- 引用不需要使用特殊的符号来访问和修改变量。
- 对引用的任何更改都会直接反映到原始变量上。
示例:
int num = 42; // 声明一个整型变量 num,初始化为 42
int& ref = num; // 声明一个整型引用 ref,引用变量 numcout << num << endl; // 输出变量 num 的值
cout << ref << endl; // 输出引用 ref 所引用变量的值ref = 99; // 修改引用 ref 所引用的变量cout << num << endl; // 输出修改后的变量 num 的值
cout << ref << endl; // 输出修改后的引用 ref 所引用变量的值
指针和引用的主要区别:
- 初始化要求:指针可以为空,也可以指向任何对象,而引用必须在声明时初始化,并且不能改变其引用的对象。
- 重新指向:指针可以在运行时重新指向不同的对象或者空值,而引用一旦初始化后不能再引用其他对象。
- 空值处理:指针可以为空值(nullptr),表示指向无效对象或空指针,而引用必须引用有效对象,不存在空引用。
3.应用实例
v1.0 传值:预期效果:修改ref变量的值。
#include <iostream>int main() {int num = 42;int ref = num; std::cout << "num: " << num << std::endl;std::cout << "ref: " << ref << std::endl;ref = 99; // 通过引用修改 num 的值std::cout << "num: " << num << std::endl;std::cout << "ref: " << ref << std::endl;return 0;
}
打印:
num: 42
ref: 42
num: 42
ref: 99
num没有改变,没有达到预期效果
。
v2.0 传引用:预期效果:修改ref变量的值。
#include <iostream>int main() {int num = 42;int& ref = num; //ref引用是num的别名,改变ref的值,也就改变num的值.std::cout << "num: " << num << std::endl;std::cout << "ref: " << ref << std::endl;ref = 99; // 通过引用修改 num 的值std::cout << "num: " << num << std::endl;std::cout << "ref: " << ref << std::endl;return 0;
}
num: 42
ref: 42
num: 99
ref: 99
num改变,达到预期效果
。
v3.0 传指针:预期效果:修改ref变量的值。
#include <iostream>int main() {int num = 42;int *ref = # //ref指针中存放的是num的地址, 改变*ref的值,num也就改变。std::cout << "num: " << num << std::endl;std::cout << "ref: " << *ref << std::endl;*ref = 99;std::cout << "num: " << num << std::endl;std::cout << "ref: " << *ref << std::endl;return 0;
}
num: 42
ref: 42
num: 99
ref: 99
num改变,达到预期效果
。
v4.0 传指针:预期效果:通过修改指针b的值,达到修改指针a和num变量的值。
#include <iostream>int main() {int num = 10;int *a = #int *b = a;printf("a = %d\n",*a);printf("b = %d\n",*b);printf("num = %d\n",num);//2.通过修改指针b,达到修改指针a和num的值,因为指针b存放的是指针a和num的地址.*b = 20;printf("a = %d\n",*a);printf("b = %d\n",*b);printf("num = %d\n",num);return 0;
}
a = 10
b = 10
num = 10
a = 20
b = 20
num = 20
指针a和num改变,达到预期效果
。
v5.0 std::vector<std::shared_ptrstd::string>插入并遍历元素
#include <iostream>
#include <vector>
#include <memory>
#include <iterator>int main() {//1.创建一个vector动态数组容器,它里面存放着指向字符串的智能指针.std::vector<std::shared_ptr<std::string>> buffers;//2.向数组中添加几个字符串,并且让指针指向它.buffers.push_back(std::make_shared<std::string>("Hello"));buffers.push_back(std::make_shared<std::string>("World"));buffers.push_back(std::make_shared<std::string>("C++"));//3.迭代器遍历访问. std::vector<std::shared_ptr<std::string>>::iterator it; for(it = buffers.begin(); it != buffers.end(); it++){printf("it = %s\n", (*it)->c_str());}// 清空数组中的指针对象buffers.clear();return 0;
}
//注意:vector容器里存放的是智能指针类型.
v6.0 修改std::vector<std::shared_ptrstd::string>插入元素的值
#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <cstring>
using namespace std;void getInputBuffers(vector<shared_ptr<string>> *buffers){(*buffers).push_back(std::make_shared<std::string>("Hello"));(*buffers).push_back(std::make_shared<std::string>("World"));
}int main(){//v1.0vector<shared_ptr<string> > inBuffers;//获取vector容器中的指针向字符串指针.getInputBuffers(&inBuffers);printf("inBuffers = %s\n",inBuffers.at(0)->data());//v2.0 :inBuffers.at(0)为vector中第一个元素,即指向字符串"Hello"的智能指针.string buf = "1234567";//定义buffer引用指向inBuffers.at(0),通过修改引用达到,修改inBuffers.at(0)的目的.//shared_ptr<string> &buffer = inBuffers.at(0);//定义buffer传指针; buffer智能指针指向vector<shared_ptr<string>>中元素,即一个指向string类型的智能指针,//因为智能指针buffer存放inBuffers.at(0)(等同于vector中一个指向string类型的智能指针),所以改变buffer指针的值,就可以改变inBuffers.at(0)指向的值。shared_ptr<string> buffer = inBuffers.at(0);memcpy(buffer->data(), buf.data(), buf.size());printf("inBuffers = %s\n",inBuffers.at(0)->data());
}
v7.0 修改std::vector<std::shared_ptrstd::string>插入元素的值(完整版本)
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <cstring>using namespace std;
int main() {int num = 10;int *a = #int *b = a;printf("a = %d\n",*a);printf("b = %d\n",*b);printf("num = %d\n",num);//2.通过修改指针b,达到修改指针a和num的值,因为指针b存放的是指针a和num的地址.*b = 20;printf("a = %d\n",*a);printf("b = %d\n",*b);printf("num = %d\n",num);//v1.0int x = 11;int &y = x;printf("x = %d\n",x);printf("y = %d\n",y);y = 22;printf("x = %d\n",x);printf("y = %d\n",y);//v2.0int *z = &y;*z = 33;printf("x = %d\n",x);printf("y = %d\n",y);shared_ptr<string> buf1 = make_shared<string>("Hello World!");printf("buf1 = %s\n",buf1->c_str());//v3.0shared_ptr<string> &buf2 = buf1;printf("buf2 = %s\n",buf2->c_str());//v4.0shared_ptr<string> buf3 = buf1;printf("buf3 = %s\n",buf3->c_str());buf2->assign("2222222");printf("buf1 = %s\n",buf1->c_str());printf("buf2 = %s\n",buf2->c_str());buf3->assign("3333333");printf("buf1 = %s\n",buf1->c_str());printf("buf3 = %s\n",buf3->c_str());//v5.0//vector<shared_ptr<string>> *buffers = new vector<std::make_shared<std::string>>("88888888888");vector<shared_ptr<string>> *buffers = new vector<std::shared_ptr<string>>;//v5.1//存放在二级指针中[0][0](*buffers).push_back(std::make_shared<std::string>("88888888888"));printf("*at(0) = %s\n",(*buffers).at(0)->data());//v5.2//存放在二级指针中[0][1]buffers->push_back(std::make_shared<std::string>("9999999"));printf("at(0) = %s\n",buffers->at(1)->data());printf("at(0) = %s\n",buffers[0][0]->data());printf("at(0) = %s\n\n",buffers[0][1]->data());//v5.3(*buffers)[0]->assign("44444");buffers[0][1]->assign("55555555");// printf("at(0) = %s\n",buffers[0][0]->data());// printf("at(1) = %s\n",buffers[0][1]->data());//v5.4vector<shared_ptr<string>> btmp1 = *buffers;vector<shared_ptr<string>> &btmp2 = *buffers;btmp2.at(0)->assign("aaaaaaaaa");btmp2.at(1)->assign("bbbbbbbbbb");// printf("at(0) = %s\n",buffers[0][0]->data());// printf("at(1) = %s\n",buffers[0][1]->data());//v6.0{char *buf = (char *)string("Hello Android!").c_str();//v6.1 buf1指针的引用,它指向buf指针.char* &buf1 = buf;printf("buf = %s\n",buf);printf("buf1 = %s\n",buf);//通过修改指针的引用buf1,达到改变buf的值.memset(buf1,0,strlen(buf1));memcpy(buf1, "Crack Data", strlen("Crack Data"));printf("buf = %s\n",buf);printf("buf1 = %s\n",buf);//v6.2 通过修改指针的buf2,达到改变buf的值.char* buf2 = buf;printf("buf = %s\n",buf);printf("buf2 = %s\n",buf);memset(buf2,0,strlen(buf2));//通过修改指针的引用buf2,达到改变buf的值.memcpy(buf2, "Hello Chromium", strlen("Hello Chromium"));printf("buf = %s\n",buf);printf("buf2 = %s\n",buf);}return 0;
}