1.Linux下/etc/profile和~/.bashrc作用
/etc/profile
和 ~/.bashrc
都是在 Linux 系统中用于配置用户环境和执行一些初始化操作的文件。
-
/etc/profile
:这个文件是系统级别的全局配置文件,适用于所有用户。当用户登录时,会先执行/etc/profile
文件中的命令和设置,然后再执行用户的个人配置文件。该文件通常包含以下内容:- 系统环境变量的设置:可以在该文件中设置系统级别的环境变量,例如
PATH
、LANG
等。 - 全局的 Shell 配置:可以设置全局范围的 Shell 相关配置,例如别名(alias)、函数、Shell 提示符等。
- 调用
/etc/profile.d/
目录下的脚本:可以在该目录下放置自定义的脚本文件,这些脚本文件将被自动执行。
- 系统环境变量的设置:可以在该文件中设置系统级别的环境变量,例如
-
~/.bashrc
:这个文件是每个用户的个人配置文件,只适用于当前用户。当用户打开一个新的终端窗口或启动一个新的交互式 Bash 会话时,会先执行~/.bashrc
文件中的命令和设置。该文件通常包含以下内容:- 用户环境变量的设置:可以在该文件中设置针对个人用户的环境变量。
- 用户自定义的 Shell 配置:可以设置用户自己喜欢的 Shell 相关配置,例如别名(alias)、函数、Shell 提示符等。
- 调用
~/.bashrc
中的其他脚本:可以在该文件中调用其他自定义的脚本文件,例如设置特定应用程序的环境变量等
2. 函数指针的使用
指针函数: 顾名思义,它的本质是一个函数,不过它的返回值是一个指针。其声明的形式如下所示:
ret *func(args, ...);
其中,func
是一个函数,args
是形参列表,ret *
作为一个整体,是 func
函数的返回值,是一个指针的形式。
下面举一个具体的实例来做说明定义:
int add(int a, int b) {
return a + b;
}
int (*add_func)(int, int) = &add;
使用时即可像这样使用 :
int result = add_func(3, 4); // 等价于 int result = add(3, 4);
也可以将函数指针作为参数传递给其他函数
可以将函数指针作为参数传递给其他函数,这样可以让函数更加通用。例如,定义一个函数 calculate
,接受一个函数指针和两个 int
类型的参数,并返回函数指针指向函数的计算结果:
int calculate(int (*func_ptr)(int, int), int a, int b)
{
return func_ptr(a, b);
}
然后,通过调用 calculate
函数,可以计算不同的函数指针指向函数的结果:
int result1 = calculate(add_func, 3, 4); // 等价于 int result1 = add(3, 4);
int result2 = calculate(sub_func, 3, 4); // 等价于 int result2 = sub(3, 4);
在上面的示例中,calculate
函数接受一个函数指针作为参数,可以根据传入的函数指针来调用不同的函数,得到不同的计算结果。
3.智能指针的使用
智能指针(Smart Pointer)是一种C++语言提供的特殊类模板,用于管理动态分配的对象的生命周期。它的作用主要有以下几点:
-
自动内存管理:智能指针提供了自动内存管理的功能,可以自动释放分配的内存,避免了手动管理内存造成的内存泄漏和悬垂指针等问题。当智能指针超出其作用域时,会自动调用析构函数来释放所管理的对象,无需手动调用
delete
。 -
防止内存泄漏:使用智能指针可以确保在异常或其他意外情况下,程序也能正确释放动态分配的内存。智能指针通过在对象销毁时自动释放内存,避免了因为忘记或错误地释放内存而造成的内存泄漏。
-
程序安全性提升:智能指针可以提高程序的安全性,避免悬垂指针和野指针的问题。智能指针会在对象销毁时自动将指针置空,避免了指向已经释放的内存导致的错误操作。
-
使用方便:智能指针可以像普通指针一样使用,通过重载运算符等方式提供了与原始指针类似的操作接口,使得代码编写更加方便和易读。
class MyClass { public: MyClass() { std::cout << "Constructor called" << std::endl; } ~MyClass() { std::cout << "Destructor called" << std::endl; } void doSomething() { std::cout << "Doing something..." << std::endl; } }; void functionWithRawPointer() { MyClass* rawPtr = new MyClass(); // 使用普通指针创建对象 rawPtr->doSomething(); delete rawPtr; // 手动释放内存 } void functionWithSmartPointer() { std::unique_ptr<MyClass> smartPtr = std::unique_ptr<MyClass>(); // 使用智能指针创建对象 smartPtr->doSomething(); // 不需要手动释放内存,智能指针会自动管理对象的生命周期 }
当然智能指针也不全是优点,相较于普通指针的确有一些缺点,主要包括:
-
额外的开销:智能指针通常需要额外的内存开销来存储管理对象生命周期所需的信息,例如引用计数、所有权信息等。这使得智能指针相对于普通指针而言更占用内存。
-
运行时性能损失:智能指针的操作可能会涉及到动态内存分配和释放,以及引用计数的更新等额外操作,这会导致一定的运行时性能损失。相比之下,普通指针是更轻量级的,直接通过地址访问对象,没有额外的开销。
-
循环引用问题:如果存在循环引用的情况,即两个或多个智能指针相互持有对方的引用,那么就会导致对象无法正确释放,从而产生内存泄漏。为解决这个问题,可以使用弱引用指针
std::weak_ptr
来打破循环引用,但需要额外的设计和注意。