C++对C语言的增强与扩展
- 格式:pdf
- 大小:243.00 KB
- 文档页数:6
C++对C语言的增强与扩展
作为一名C++开发者,我在日常编程中经常会使用到C++对C语言的一些增强特性。这些特性让
C++编程更加方便、高效,也让代码更具可读性和可维护性。今天,我就来和大家分享一下C++在这
方面的一些独特之处。
作用域运算符
在C++中,双冒号
::被称为作用域运算符。它可以用来解决标识符的归属问题,即指明某个标识符
属于哪个命名空间、类或枚举。
举个例子,如果全局作用域和局部作用域都定义了同名的变量
x,那么在局部作用域内可以用
::来
区分它们:
可以看到,在函数
foo内部,
x默认指向局部变量,而
::x则明确指向全局变量。
命名空间
命名空间(namespace)是C++中一个非常重要的概念。它提供了一种将相关的类、函数和变量等
封装到一起的机制,可以有效避免命名冲突。
定义命名空间
使用
namespace关键字可以定义一个命名空间,例如:
上述代码定义了一个名为
MySpace的命名空间,其中包含一个整型变量
x和一个函数
foo。
需要注意的是,命名空间只能定义在全局作用域,不能定义在函数内部。int x = 0; // 全局变量x
void foo() {
int x = 1; // 局部变量x
cout << "局部x: " << x << endl; // 输出1
cout << "全局x: " << ::x << endl; // 输出0
}
namespace MySpace {
int x = 0;
void foo() {
cout << "MySpace::foo()" << endl;
}
}
嵌套的命名空间
命名空间可以嵌套定义,形成层次结构。例如:
这里在
OuterSpace内部又定义了一个
InnerSpace。访问
x时需要加上完整的命名空间限
定:
OuterSpace::InnerSpace::x。
扩展命名空间
C++允许我们随时向已有的命名空间中添加新的成员。这给予了我们很大的灵活性。
这种写法和Java等语言有很大不同,在Java中命名空间一经定义就不能改变了。
命名空间中的函数
如果我们在命名空间内部声明了函数,而要在外部定义它们,需要在函数名前加上命名空间限定符。
例如:
匿名命名空间namespace OuterSpace {
namespace InnerSpace {
int x = 0;
}
}
namespace MySpace {
int x = 0;
}
// 在其他地方扩展MySpace
namespace MySpace {
int y = 1;
}
namespace MySpace {
void foo(); // 函数声明
void bar() { // 函数定义
// ...
}
}
// 在命名空间外部定义foo
void MySpace::foo() {
// ...
}
有时候我们希望定义一些只在当前文件内部可见的标识符,可以使用匿名命名空间:
匿名命名空间中的标识符相当于加了
static
限定符,只能在当前文件中访问。
命名空间别名
如果命名空间的名字比较长,我们可以给它起个别名,以便在后续代码中简化书写:
using声明
如果我们只需要使用命名空间中的某个标识符,可以使用
using关键字引入到当前作用域,而不必写
完整的限定符:
需要注意的是,
using声明可能带来命名冲突的问题。如果引入的标识符与当前作用域中已有的重
名了,编译器会报错。
using指示
与
using声明不同,
using指示会将整个命名空间引入到当前作用域。例如:
这种用法虽然方便,但也更容易造成命名污染和冲突,需要谨慎使用。特别是不要在头文件中使用
using指示,这可能给其他文件引入难以调试的错误。namespace {
int x = 0;
}
namespace VeryLongName {
void foo() {
// ...
}
}
namespace Short = VeryLongName;
// 现在可以通过Short::foo()来调用了
using MySpace::foo; // 引入MySpace中的foo
foo(); // 直接使用foo
using namespace MySpace;
x = 5; // 相当于MySpace::x
foo(); // 相当于MySpace::foo()
C++对C的其他增强
除了上述两个重要特性,C++还对C语言做了很多其他的改进和扩展。
bool类型
C++新增了
bool类型,用于表示真值。取值为
true或
false,使逻辑表达更加直观、易懂。
结构体增强
在C语言中,使用结构体变量必须加上
struct关键字,而在C++中则可以省略。同时C++还允许在结
构体内部定义函数,使得结构体更接近于类的概念。
三目运算符
C++中的三目运算符可以返回左值引用,而C语言只能返回值。这使得我们可以给三目运算符的结果
赋值:
const增强
在C语言中,使用
const修饰变量虽然意味着只读,但我们仍然可以通过指针修改它的值。而C++则
保证
const变量真正不可改变。
另外,当
const与引用结合使用时,可以发挥出更大的作用。
const引用可以指向临时变量、字面量,
并且可以接受非
const类型的参数,这大大提高了程序的灵活性。
引用
引用是C++中一个非常独特和实用的概念。它相当于变量的"别名",对引用的操作实际上是对原变
量的操作。struct Person {
void sayHello() {
cout << "Hello, my name is " << name << endl;
}
string name;
int age;
};
Person p = {"Tom", 18}; // 无需struct关键字
p.sayHello();
int x = 1, y = 2;
(x < y ? x : y) = 3; // 相当于x = 3
引用分为左值引用和右值引用。左值引用主要用于函数参数传递,可以避免拷贝带来的开销。例如:
右值引用则主要用于移动语义,可以避免不必要的拷贝,提高程序效率。关于引用的具体用法,我会在
后续文章中详细介绍。
内联函数
内联函数是C++的一个重要优化手段。通过
inline关键字,编译器会在调用处直接展开函数体,从而
消除函数调用的开销。
内联函数主要适用于一些简短、频繁调用的函数。需要注意的是,
inline只是一种请求,编译器不保
证一定会内联。
函数重载
C++支持函数重载,即在同一作用域内可以定义名字相同但参数不同的函数。编译器会根据实参的
类型和数量自动匹配对应的函数。例如:
默认参数
在C++中,我们可以为函数参数指定默认值。当调用函数时如果没有传入对应的实参,则使用默认
值。例如:void foo(vector
// 通过引用v直接修改原vector的内容
}
int add(int x, int y) {
return x + y;
}
double add(double x, double y) {
return x + y;
}
add(1, 2); // 调用第一个add
add(1.0, 2.0); // 调用第二个add
void foo(int x, int y = 0) {
// ...
}
foo(1); // 相当于foo(1, 0)
foo(1, 2); // y使用实参2
需要注意的是,默认参数要从右到左连续定义,不能间隔。
占位参数
占位参数只有参数类型,没有参数名,在函数体内不能使用它的值。它的主要目的是凑齐参数列表,以
便于函数重载。例如:
void foo(int);
void foo(int, int = 0); // 占位参数,以便与上一个foo重载