美文网首页
C++ 高级特性

C++ 高级特性

作者: 码农朱同学 | 来源:发表于2022-09-22 09:39 被阅读0次

    C++ 命名空间

    定义命名空间

    namespace namespace_name {
       // 代码声明
    }
    

    您可以使用 using namespace 指令,这样在使用命名空间时就可以不用在前面加上命名空间的名称。这个指令会告诉编译器,后续的代码将使用指定的命名空间中的名称。

    命名空间可以嵌套,您可以在一个命名空间中定义另一个命名空间,如下所示:

    namespace namespace_name1 {
       // 代码声明
       namespace namespace_name2 {
          // 代码声明
       }
    }
    

    您可以通过使用 :: 运算符来访问嵌套的命名空间中的成员:

    // 访问 namespace_name2 中的成员
    using namespace namespace_name1::namespace_name2;
     
    // 访问 namespace_name1 中的成员
    using namespace namespace_name1;
    
    #include <iostream>
    using namespace std;
     
    // 第一个命名空间
    namespace first_space{
       void func(){
          cout << "Inside first_space" << endl;
       }
       // 第二个命名空间
       namespace second_space{
          void func(){
             cout << "Inside second_space" << endl;
          }
       }
    }
    using namespace first_space::second_space;
    int main ()
    {
     
       // 调用第二个命名空间中的函数
       func();
       
       return 0;
    }
    

    当上面的代码被编译和执行时,它会产生下列结果:

    Inside second_space
    

    C++ 模板

    模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。

    模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。

    每个容器都有一个单一的定义,比如 向量,我们可以定义许多不同类型的向量,比如 vector <int> 或 vector <string>。

    您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。

    template <typename type> ret-type func-name(parameter list)
    {
       // 函数的主体
    }
    

    实例:

    #include <iostream>
    #include <vector>
    #include <cstdlib>
    #include <string>
    #include <stdexcept>
     
    using namespace std;
     
    template <class T>
    class Stack { 
      private: 
        vector<T> elems;     // 元素 
     
      public: 
        void push(T const&);  // 入栈
        void pop();               // 出栈
        T top() const;            // 返回栈顶元素
        bool empty() const{       // 如果为空则返回真。
            return elems.empty(); 
        } 
    }; 
     
    template <class T>
    void Stack<T>::push (T const& elem) 
    { 
        // 追加传入元素的副本
        elems.push_back(elem);    
    } 
     
    template <class T>
    void Stack<T>::pop () 
    { 
        if (elems.empty()) { 
            throw out_of_range("Stack<>::pop(): empty stack"); 
        }
        // 删除最后一个元素
        elems.pop_back();         
    } 
     
    template <class T>
    T Stack<T>::top () const 
    { 
        if (elems.empty()) { 
            throw out_of_range("Stack<>::top(): empty stack"); 
        }
        // 返回最后一个元素的副本 
        return elems.back();      
    } 
     
    int main() 
    { 
        try { 
            Stack<int>         intStack;  // int 类型的栈 
            Stack<string> stringStack;    // string 类型的栈 
     
            // 操作 int 类型的栈 
            intStack.push(7); 
            cout << intStack.top() <<endl; 
     
            // 操作 string 类型的栈 
            stringStack.push("hello"); 
            cout << stringStack.top() << std::endl; 
            stringStack.pop(); 
            stringStack.pop(); 
        } 
        catch (exception const& ex) { 
            cerr << "Exception: " << ex.what() <<endl; 
            return -1;
        } 
    }
    

    C++ 预处理器

    预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。

    所有的预处理器指令都是以井号(#)开头,只有空格字符可以出现在预处理指令之前。预处理指令不是 C++ 语句,所以它们不会以分号(;)结尾。

    我们已经看到,之前所有的实例中都有 #include 指令。这个宏用于把头文件包含到源文件中。

    C++ 还支持很多预处理指令,比如 #include、#define、#if、#else、#line 等,让我们一起看看这些重要指令。

    #define macro-name replacement-text 
    
    #include <iostream>
    using namespace std;
     
    #define PI 3.14159
     
    int main ()
    {
        cout << "Value of PI :" << PI << endl; 
        return 0;
    }
    

    C++ 信号处理

    信号是由操作系统传给进程的中断,会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上,可以通过按 Ctrl+C 产生中断。

    有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作。这些信号是定义在 C++ 头文件 <csignal> 中

    C++ 信号处理库提供了 signal 函数,用来捕获突发事件。以下是 signal() 函数的语法:

    void (*signal (int sig, void (*func)(int)))(int); 
    
    #include <iostream>
    #include <csignal>
    #include <unistd.h>
     
    using namespace std;
     
    void signalHandler( int signum )
    {
        cout << "Interrupt signal (" << signum << ") received.\n";
     
        // 清理并关闭
        // 终止程序  
     
       exit(signum);  
     
    }
     
    int main ()
    {
        // 注册信号 SIGINT 和信号处理程序
        signal(SIGINT, signalHandler);  
     
        while(1){
           cout << "Going to sleep...." << endl;
           sleep(1);
        }
     
        return 0;
    }
    

    C++ 多线程

    创建线程

    #include <pthread.h>
    pthread_create (thread, attr, start_routine, arg) 
    
    // 演示多线程的CPP程序
    // 使用三个不同的可调用对象
    #include <iostream>
    #include <thread>
    using namespace std;
     
    // 一个虚拟函数
    void foo(int Z)
    {
        for (int i = 0; i < Z; i++) {
            cout << "线程使用函数指针作为可调用参数\n";
        }
    }
     
    // 可调用对象
    class thread_obj {
    public:
        void operator()(int x)
        {
            for (int i = 0; i < x; i++)
                cout << "线程使用函数对象作为可调用参数\n";
        }
    };
     
    int main()
    {
        cout << "线程 1 、2 、3 "
             "独立运行" << endl;
     
        // 函数指针
        thread th1(foo, 3);
     
        // 函数对象
        thread th2(thread_obj(), 3);
     
        // 定义 Lambda 表达式
        auto f = [](int x) {
            for (int i = 0; i < x; i++)
                cout << "线程使用 lambda 表达式作为可调用参数\n";
        };
     
        // 线程通过使用 lambda 表达式作为可调用的参数
        thread th3(f, 3);
     
        // 等待线程完成
        // 等待线程 t1 完成
        th1.join();
     
        // 等待线程 t2 完成
        th2.join();
     
        // 等待线程 t3 完成
        th3.join();
     
        return 0;
    }
    

    c++ 11 之后有了标准的线程库:

    #include <iostream>
    
    #include <thread>
    
    std::thread::id main_thread_id = std::this_thread::get_id();
    
    void hello()  
    {
        std::cout << "Hello Concurrent World\n";
        if (main_thread_id == std::this_thread::get_id())
            std::cout << "This is the main thread.\n";
        else
            std::cout << "This is not the main thread.\n";
    }
    
    void pause_thread(int n) {
        std::this_thread::sleep_for(std::chrono::seconds(n));
        std::cout << "pause of " << n << " seconds ended\n";
    }
    
    int main() {
        std::thread t(hello);
        std::cout << t.hardware_concurrency() << std::endl;//可以并发执行多少个(不准确)
        std::cout << "native_handle " << t.native_handle() << std::endl;//可以并发执行多少个(不准确)
        t.join();
        std::thread a(hello);
        a.detach();
        std::thread threads[5];                         // 默认构造线程
    
        std::cout << "Spawning 5 threads...\n";
        for (int i = 0; i < 5; ++i)
            threads[i] = std::thread(pause_thread, i + 1);   // move-assign threads
        std::cout << "Done spawning threads. Now waiting for them to join:\n";
        for (auto &thread : threads)
            thread.join();
        std::cout << "All threads joined!\n";
    }
    

    C++ Web 编程

    什么是 CGI?
    公共网关接口(CGI),是一套标准,定义了信息是如何在 Web 服务器和客户端脚本之间进行交换的。
    CGI 规范目前是由 NCSA 维护的,NCSA 定义 CGI 如下:
    公共网关接口(CGI),是一种用于外部网关程序与信息服务器(如 HTTP 服务器)对接的接口标准。
    目前的版本是 CGI/1.1,CGI/1.2 版本正在推进中。

    #include <iostream>
    #include <vector>  
    #include <string>  
    #include <stdio.h>  
    #include <stdlib.h> 
     
    #include <cgicc/CgiDefs.h> 
    #include <cgicc/Cgicc.h> 
    #include <cgicc/HTTPHTMLHeader.h> 
    #include <cgicc/HTMLClasses.h>
     
    using namespace std;
    using namespace cgicc;
     
    int main ()
    {
       Cgicc cgi;
     
       cout << "Content-type:text/html\r\n\r\n";
       cout << "<html>\n";
       cout << "<head>\n";
       cout << "<title>CGI 中的文件上传</title>\n";
       cout << "</head>\n";
       cout << "<body>\n";
     
       // 获取要被上传的文件列表
       const_file_iterator file = cgi.getFile("userfile");
       if(file != cgi.getFiles().end()) {
          // 在 cout 中发送数据类型
          cout << HTTPContentHeader(file->getDataType());
          // 在 cout 中写入内容
          file->writeToStream(cout);
       }
       cout << "<文件上传成功>\n";
       cout << "</body>\n";
       cout << "</html>\n";
       
       return 0;
    }
    

    C++ STL 教程

    在前面的章节中,我们已经学习了 C++ 模板的概念。C++ STL(标准模板库)是一套功能强大的 C++ 模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量、链表、队列、栈。

    下面的程序演示了向量容器(一个 C++ 标准的模板),它与数组十分相似,唯一不同的是,向量在需要扩展大小的时候,会自动处理它自己的存储需求:

    #include <iostream>
    #include <vector>
    using namespace std;
     
    int main()
    {
       // 创建一个向量存储 int
       vector<int> vec; 
       int i;
     
       // 显示 vec 的原始大小
       cout << "vector size = " << vec.size() << endl;
     
       // 推入 5 个值到向量中
       for(i = 0; i < 5; i++){
          vec.push_back(i);
       }
     
       // 显示 vec 扩展后的大小
       cout << "extended vector size = " << vec.size() << endl;
     
       // 访问向量中的 5 个值
       for(i = 0; i < 5; i++){
          cout << "value of vec [" << i << "] = " << vec[i] << endl;
       }
     
       // 使用迭代器 iterator 访问值
       vector<int>::iterator v = vec.begin();
       while( v != vec.end()) {
          cout << "value of v = " << *v << endl;
          v++;
       }
     
       return 0;
    }
    

    相关文章

      网友评论

          本文标题:C++ 高级特性

          本文链接:https://www.haomeiwen.com/subject/dukvortx.html