1. 动态内存分配介绍
在C++中,内存的分配和释放可以使用静态和动态两种方式。静态分配的内存由编译器在编译时刻确定并分配,在程序运行时刻始终存在,直到程序结束才会被释放。但是静态分配存在一些限制,如大小固定,无法根据程序运行时需要动态变化。而动态分配可以在程序运行时动态分配内存,大小和位置可以根据程序的需要灵活调整,但也需要程序员自己负责在合适的时刻释放内存。
在C++中,动态分配内存使用new和delete操作符。new操作符用于动态分配内存,其语法如下:
指针变量 = new 类型名;
例如,可以使用new操作符动态分配一个整型变量:
int *p = new int;
这里p是一个指向动态分配的int类型变量的指针。使用delete操作符可以释放掉这个内存:
delete p;
需要注意的是,使用new动态分配的内存一定要在合适的时刻使用delete释放,否则会产生内存泄漏,导致程序运行效率下降。
1.1 动态分配数组
除了动态分配单独的变量外,C++中还可以使用new操作符动态分配数组。其语法如下:
指针变量 = new 类型名[元素个数];
例如,可以使用new操作符动态分配一个包含10个int类型元素的数组:
int *p = new int[10];
这里p是一个指向动态分配的int类型数组的指针。和动态分配单独的变量一样,使用delete操作符可以释放掉这个数组:
delete[] p;
需要注意的是,释放掉动态分配的数组时要使用delete[]操作符,否则会导致内存泄漏。
2. 命名空间介绍
在C++中,命名空间是一种封装机制,用于避免命名冲突。命名空间可以将相同名字的变量,函数、类等放在不同的命名空间中,使它们的作用域只限于该命名空间内。命名空间的定义方式如下:
namespace 命名空间名 {
// 命名空间内容
}
例如,下面定义了一个命名空间myNamespace:
namespace myNamespace {
int x = 10;
void printX() {
std::cout << "x = " << x << std::endl;
}
}
在使用命名空间中的内容时可以使用作用域解析运算符"::",将其限定到特定的命名空间中,例如:
myNamespace::printX();
除了定义自己的命名空间外,C++标准库中定义了全局命名空间std,其中包含了众多常用的函数、类和变量。在使用标准库中的内容时,一般需要使用作用域解析运算符将其限定到std命名空间中,例如使用cout输出:
std::cout << "Hello, World!" << std::endl;
需要注意的是,在大型程序中,使用命名空间可以有效避免代码冲突和混乱。但是过度使用命名空间会使代码冗长和维护困难,因此需要根据实际情况灵活使用。
2.1 命名空间别名
为了方便使用命名空间中的内容,C++中还提供了命名空间别名的机制,用于给命名空间起别名。命名空间别名的定义方式如下:
namespace 别名 = 命名空间名;
例如,可以使用以下语句定义myNamespace的别名:
namespace myAlias = myNamespace;
这样可以通过别名myAlias来访问原始命名空间myNamespace中的内容:
myAlias::printX();
2.2 匿名命名空间
匿名命名空间是一种定义在全局作用域内的无名命名空间,其中定义的内容可以被当前文件内所有函数访问,但对其他文件不可见。其定义方式如下:
namespace {
// 命名空间内容
}
例如,下面的程序定义了一个匿名命名空间,并在其中定义了一个函数用于输出hello:
// anonymous_namespace.cpp
#include <iostream>
namespace {
void hello() {
std::cout << "Hello, World!" << std::endl;
}
}
int main() {
hello();
return 0;
}
因为匿名命名空间中的内容只能在当前文件内访问,因此上述程序的输出也只能在该文件中看到:
Hello, World!
匿名命名空间也可以用于定义内部链接的全局变量和函数,以避免与其他文件中的变量和函数发生命名冲突。