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) {

// 通过引用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重载