C++对C的扩展(上)

简介: C++对C的扩展

C++对C的扩展


::作用域运算符


通常情况下,如果有两个同名变量,一个是全局变量,一个是局部变量,那么局部变量在其作用域中有较高的优先权, 它将屏蔽全局变量(就近原则)


代码示例

#include <iostream>
#include <string>
#include <iostream>
using namespace std;
int a = 10;
void test()
{
    int a = 20;
    cout << a << endl;
    cout << ::a << endl;
}
int main(int argc, char* argv[])
{
    test();
    return 0;
}


namespace 命名空间


在C++中,名称可以是符号常量、变量、函数、结构、枚举、类和对象等。工程越大,名称相互冲突的可能性越大。另外使用多个厂商的类库时,也可能导致名称冲突。为了避免在大规模程序设计中,以及在程序员使用各种各样的C++库的时候,这些表示符的命名发生冲入,标准的C++引入关键字namespace,可以更好的控制标识符的作用域。


代码示例

#include <iostream>
#include <string>
#include <iostream>
using namespace std;
namespace A
{
    int a = 10;
    namespace C
    {
        int a = 200;
    }
    void c()
    {
        cout << "A :: C" << endl;
    }
}
namespace B
{
    int a = 20;
    void c();
}
void B::c()
{
    cout << "B :: C" <<endl;
}
void test()
{
    cout << A::a << endl;
    cout << A::C::a << endl;
    cout << B::a << endl;
    A::c();
    B::c();
}
int main(int argc, char* argv[])
{
    test();
    return 0;
}


命名空间的使用注意


  • 命名空间只能在全局范围定义
  • 命名空间内可以嵌套命名空间
  • 命名空间是开放的,可以随时把新的成员加入已有的命名空间中
  • 命名空间可以存放变量、函数、类等
  • 命名空间中的函数可以在命名空间外部定义


无名命名空间和命名空间别名


意味着命名空间的标识符只能在本文件内访问,相当于给这个标识符加上了static,使得其可以作为内部连接

#include <iostream>
#include <string>
#include <iostream>
using namespace std;

namespace
{
    int a =300;
    void func()
    {
        cout << " im 啊" <<endl;
    }
}
namespace vewrylongnamespace
{
    void func()
    {
        cout << "vewrylongnamespace" <<endl;
    }
}
void test()
{
    cout << a << endl;
    func();
    namespace aa = vewrylongnamespace;
    aa::func();
}
int main(int argc, char* argv[])
{
    test();
    return 0;
}


using声明


  • 表示从using开始,下面的变量使用using声明的命名空间中优先获取,简化对命名空间成员访问的操作。
  • 简化的代价是容易造成命名空间的冲突。
  • using 指明使用具体的命名空间的成员。如果出现冲突则会报错,不会和全局变量冲突。
  • using遇到函数重载的时候,指定函数会对所有的函数起作用。
#include <iostream>
#include <string>
#include <iostream>
using namespace std;
namespace A
{
    int a = 10;
}
namespace vewrylongnamespace
{
    int a = 20;
}
void test()
{
    // int a = 100;
    using namespace A;
    // using A::a;
    cout << a << endl;
}
int main(int argc, char* argv[])
{
    test();
    return 0;
}
#include <iostream>
#include <string>
#include <iostream>
using namespace std;
namespace B
{
    int a = 20;
    void func()
    {
        cout << "B" <<endl;
    }
    void func(int a)
    {
        cout << "func with a" <<endl;
    }
}
void test()
{
    using B::func;
    func(1);
}
int main(int argc, char* argv[])
{
    test();
    return 0;
}


注意: 不同命名空间的同名成员使用的时候注意二义性。


语法的增强


  • 全局变量的增强检测
  • 类型检查增强,函数参数和返回值必须有类型,不可以缺省
  • 严格的类型转换
  • struct类型加强


struct的增强


  • C中定义结构体在使用的时候需要加上struct关键字, C++不需要
  • C中的结构体只能定义变量,不能定义成员函数, C++都可以


bool 类型


标准C++的bool类型有两种内建常量(true 和false)表示状态,占一个字节大小,只有两个值

C99之后才有和C++一样的bool值。


三目运算符


C语言三目运算符返回的为数据值,为右值,不能赋值

C++返回的为变量本身(引用), 为左值,可以赋值


const 关键字


C语言


  • const 修饰全局变量,内存空间在文字常量区(属于全局区,只读),不能通过num的地址修改空间内容。
  • const修饰局部变量时,变量名只读,内存在栈区(可读可写),可以通过变量的地址间接修改空间内容。


C++


  • 在C++中一个const不必创建内存空间,是否分配依赖于如何使用;而在C中一个const总是需要一块内存空间。
  • 在函数之外的const默认是内部连接,在其他文件无法访问。如果想在别的文件中使用则必须加extern。
  • C++中对于基础类型,系统不会给data开辟空间,系统会把数据放入符号表中,data可以看成真正的常量。
  • 对data取地址的时候,系统会给data开辟内存空间。
  • 使用一个变量给只读变量初始化的时候也会开辟空间,这种情况下不会将const变量放入符号表中,因此可以修改其值。
  • 对于自定义数据类型,也会开辟空间。
  • 尽量使用const替换宏。
#include <iostream>
#include <string>
#include <iostream>
using namespace std;
void test()
{
    const int data = 10;
    cout << data << endl;
    int *p = (int *)&data;
    *p = 2000;
    cout << *p << endl;
    cout << data << endl;
    int a = 10;
    const int b = a;
    int *pp = (int *)&b;
    *pp = 200;
    cout << *pp << endl;
    cout << b << endl;

}
int main(int argc, char* argv[])
{
    test();
    return 0;
}

const 替换define


  • const 有类型,可以进行编译器类型安全检查,#define没有类型,不会进行类型检查
  • const有作用域,而#define没有作用域,默认到文件末尾都是有效的


引用


引用是C++对C的重要扩充。在C/C++中,指针的作用基本都是一样的,但是在C++中增加了另外一种给函数传递地址的途径,这就是按引用传递,它也存在于其他语言中,不是C++发明的。


语法:

  • &和别名结合表示引用
  • 给某个变量取别名,就定义某个变量
  • 从上往下替换
int num = 10;
int &a = num; // 表明a是引用变量, a是num的别名


注意:

  • 引用必须初始化
  • 一旦初始化,不能随便修改


C++对C的扩展(下):https://developer.aliyun.com/article/1459383

目录
相关文章
|
6月前
|
设计模式 uml C++
C++中的装饰器模式:灵活地扩展功能
C++中的装饰器模式:灵活地扩展功能
96 0
|
6月前
|
安全 编译器 程序员
C++对C的扩展(下)
C++对C的扩展
50 0
|
6月前
|
算法 数据处理 C++
【C++ 20 新特性 算法和迭代器库的扩展和泛化 Ranges】深入浅出C++ Ranges库 (Exploring the C++ Ranges Library)
【C++ 20 新特性 算法和迭代器库的扩展和泛化 Ranges】深入浅出C++ Ranges库 (Exploring the C++ Ranges Library)
783 1
|
1月前
|
存储 C++ UED
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展
本文介绍了如何通过四步实现C++插件化编程,实现功能定制与扩展。主要内容包括引言、概述、需求分析、设计方案、详细设计、验证和总结。通过动态加载功能模块,实现软件的高度灵活性和可扩展性,支持快速定制和市场变化响应。具体步骤涉及配置文件构建、模块编译、动态库入口实现和主程序加载。验证部分展示了模块加载成功的日志和配置信息。总结中强调了插件化编程的优势及其在多个方面的应用。
231 64
|
2月前
|
存储 设计模式 编译器
C++(十三) 类的扩展
本文详细介绍了C++中类的各种扩展特性,包括类成员存储、`sizeof`操作符的应用、类成员函数的存储方式及其背后的`this`指针机制。此外,还探讨了`const`修饰符在成员变量和函数中的作用,以及如何通过`static`关键字实现类中的资源共享。文章还介绍了单例模式的设计思路,并讨论了指向类成员(数据成员和函数成员)的指针的使用方法。最后,还讲解了指向静态成员的指针的相关概念和应用示例。通过这些内容,帮助读者更好地理解和掌握C++面向对象编程的核心概念和技术细节。
|
2月前
|
图形学 C++ C#
Unity插件开发全攻略:从零起步教你用C++扩展游戏功能,解锁Unity新玩法的详细步骤与实战技巧大公开
【8月更文挑战第31天】Unity 是一款功能强大的游戏开发引擎,支持多平台发布并拥有丰富的插件生态系统。本文介绍 Unity 插件开发基础,帮助读者从零开始编写自定义插件以扩展其功能。插件通常用 C++ 编写,通过 Mono C# 运行时调用,需在不同平台上编译。文中详细讲解了开发环境搭建、简单插件编写及在 Unity 中调用的方法,包括创建 C# 封装脚本和处理跨平台问题,助力开发者提升游戏开发效率。
201 0
|
5月前
|
程序员 C语言 C++
【C++语言】继承:类特性的扩展,重要的类复用!
【C++语言】继承:类特性的扩展,重要的类复用!
|
6月前
|
存储 编译器 C++
C++新特性 扩展和聚合类型
C++新特性 扩展和聚合类型
|
6月前
|
算法 Java C++
【C/C++ 内存知识扩展】内存不足的可能性分析
【C/C++ 内存知识扩展】内存不足的可能性分析
63 0
|
安全 编译器 C语言
c++学习之c++对c的扩展1
c++学习之c++对c的扩展1
109 0