C++ 重定义的一些问题

文章讨论了C++中头文件重复包含导致的重定义问题,特别是pragmaonce和#ifndef宏的使用。LNK2005错误通常由于变量在不同编译单元中被多次定义引起。解决方案包括在源文件中使用extern声明变量或在头文件中使用static关键字来避免重定义。
摘要由CSDN通过智能技术生成

前言

首先从一个问题引入,先看一个遇到 LINK2005 问题的项目,由一个头文件与两个源文件组成,内容分别为

//a.h
#pragma once        
int a;
//a.cpp
#include "a.h"
//main.cpp
#include "a.h"
#include<iostream>
using namespace std;
int main() {
	cout << 3;
}

这是简化后的项目,该项目报错如图
在这里插入图片描述
于是产生了疑惑,为什么已经使用 #pragma once 确保头文件只被 include 一次,但仍然重定义。

pragma once 与 #ifndef 的作用

众所周知,#pragma once 与 #ifndef 作用类似,都是用于确保头文件只被引用一次,比如下面的一个由两个头文件与一个源文件组成的项目

//a.h      
int a;
//b.h
#include "a.h"
//main.cpp
#include "b.h"
#include "a.h"
#include<iostream>
using namespace std;
int main() {
	cout << 3;
}

此时报错如图
在这里插入图片描述
因为在引入 b.h 文件时,编译器已经为 a.h 中的 a 定义过,因此再次引用 a.h 时发生重定义错误,该错误在给 a.h 文件加上 #pragma once 后解决。

LNK2005 问题

但是为什么即使加了 #pragma once 还是会出现前言中的错误呢,因为前言中的错误与 C2086 不同,LNK2005 源于链接时的重定义错误。因为在编译 a.cpp 已经给 a.h 中的 a 定义过,在编译 main.cpp 后又给 a.h 中的 a 再次定义,因此在将 a.obj 与 main.obj 链接时产生错误。这就要考虑到 C++ 中变量的声明与定义与函数的不同。

变量的声明与定义

定义:指为变量分配内存空间
声明:只是告知编译器变量的类型与名字
在 C++ 中,只有

extern int a;

是声明变量的形式,除此之外都是变量的定义,因此前文 a.h 中的 int a;会导致重定义问题。

解决方法

解决方法有二,
1、在源文件中定义变量,即在 int a;前加 extern 前缀。
2、如果一定要在头文件中初始化变量,则可在变量前加 static 前缀,避免其被重定义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值