• [C++]关于头文件中的防卫式声明


    大家知道,我们写.h文件时,通常会加上防卫式声明,有以下两种方式:

    1. 宏定义

    1
    2
    3
    4
    #ifndef _FILENAME_
    #define _FILENAME_
    //...
    #endif

    2. 编译器指令

    1
    #pragma once

      

    但是,为什么头文件中需要添加这种防卫式声明呢?如果没有这样的声明,会出现怎样的问题。这里,先看一个例子。

    -- "Car.h",代码如下(并没有添加防卫式声明):

    1
    2
    3
    4
    5
    // Car.h
    class Car
    {
    // ...
    };

    -- "Person.h",代码如下(包含了Car.h文件):

    1
    2
    3
    4
    5
    6
    7
    // Person.h
    #include "Car.h"
    class Person
    {
    public:
        Car car;
    };

    -- 在"main.cpp"中,我们同时include两个头文件:

    1
    2
    3
    4
    5
    6
    // main.cpp
    #include "Car.h"
    #include "Person.h"
    int main(int argc, const char * argv[]) <br>{
        Person p;
    }

    此时,我们会发现编译出错:Redefinition of 'Car'.

    可是为什么会出现这样的情况呢?

    我们需要知道,在预编译阶段,编译器会把.h文件展开,即main.cpp中的代码可以看做是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class Car
    {
        // ...
    };
     
    class Car
    {
        // ...
    };
     
    class Person
    {
    public:
        Car car;
    };
     
    int main(int argc, const char * argv[]) {
        Person p;
    }

    所以,我们可以知道防卫式声明的作用是:防止由于同一个头文件被包含多次,而导致了重复定义。

    在这两种声明方式中:

      #ifndef 依赖于宏定义名,当宏已经定义时,#endif之前的代码就会被忽略,但是这里需要注意宏命名重名的问题;

      #pragma once 只能保证同一个文件不会被编译多次,但是当两个不同的文件内容相同时,仍然会出错。而且这是微软提供的编译器命令,当代码需要跨平台时,需要使用宏定义方式。

    https://www.cnblogs.com/xyq10612/p/5910933.html

  • 相关阅读:
    skywalking
    数据库中redoundo的介绍
    grafana
    查看linux的ssh服务信息及运行状态
    获取当前路由
    使VM可以用内网ip访问
    sentinel
    一,安装dotnet
    数据模型(Data Model)
    Vue——获取对象类型
  • 原文地址:https://www.cnblogs.com/swefii/p/10505674.html
Copyright © 2020-2023  润新知