.h与.cpp在连接时重复定义问题

本文详细解析了C++中多文件编译的问题,包括函数与全局变量在不同源文件间的声明与定义规则,以及如何避免重复定义的错误。通过实例说明了头文件中函数声明与定义的区别,以及全局变量的正确声明方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

一、多文件中函数的声明与定义

A.h

#pragma once
#include <iostream>

void fun() {
	std::cout << "我是fun()函数" << std::endl;
}

a.cpp

#include "pch.h"
#include "A.h"

int main()
{
	return 0;
}

b.cpp


#include"pch.h"
#include<iostream>
#include "A.h"

链接报错  重复定义  

 

#pragma once
#include <iostream>

void fun();

 改成函数声明则编译链接通过   头文件中尽量不要定义函数  如果非要定义不可 要注意包含头文件时避免重复定义

解决方法:

1.将函数定义声明为inline  

2.定义一个类 将这个函数写在类中

 

#pragma once
#include <iostream>

void fun();

class A {
public:
	void f() {

	}
};

现在定义一个类  类中的成员函数默认为内联(inline) 一个.h文件可以被多个cpp文件包含  不会重复定义

#pragma once
#include <iostream>
class A {
public:
	void f1() {

	}
	void f2();
};
void A::f2() {

}

类内声明一个函数  同时在本.h文件中实现它  仍然重复定义

如果新建一个c.cpp文件  将

void A::f2() {

}

放在c.cpp文件 中   其他两个cpp同时包含A.h文件    是可以编译链接通过的

 

二、多文件中全局变量的声明与定义

下面看下全局变量在.h文件中的问题

#pragma once
#include <iostream>

int a;

 我在A.h中这样定义了一个变量

在a.cpp和b.cpp中include"A.h"

编译链接:

出现重定义

 

解决方法: 

将头文件中的全局变量声明为extern   然后在其他包含该头文件的源文件中  任何一个(只能是一个)  定义一下(不加extern)  这样全局变量在整个工程中有效  ,这时其他源文件用到这个全局变量是  无需重新定义 直接用即可.

至于选择在哪个源文件中定义该变量,就看这个变量要在哪个源文件中初始化

举个例子:

 

a.cpp

#include"A.h"
class stu {
public:
	int b = a;
	void println() {
		std::cout << "b = " << b << std::endl;
	}
};

int main()
{
	stu s;
	s.println();
	system("pause");
	return 0;
}

可见 我的a的声明与定义并没有出现在a.cpp中  但是由于是静态的  已经可以直接只用了 并且结果正确。

 

函数与变量的声明与定义:

声明:告诉编译器变量的类型 在哪里 或者函数的特征(返回值 参数类型 个数)
定义:告诉编译器 在此处分配存储空间 建立变量和函数

同一变量定义只有一个(干嘛要多处分配空间呢 内存很宝贵的~)
但是可以声明多次

变量有点混淆--
int a; 是个声明 也是个定义
extern int a; 只是声明
所以声明包含定义,有足够的信息让编译器建立变量的声明 就是一个定义
为了让int a;不是定义(别给a分配空间) 前面加extern吧
(所以 extern int a=1;是要出错的 )

摘自https://blog.csdn.net/u010063827/article/details/78280854

 

画个图:

函数的规则:

 

变量的规则:

 

 

 

小总结:
1.  严格按照.h文件中声明函数原型  .cpp中对其实现  (类的成员函数除外)

2. 如果头文件中出现全局变量  用extern先声明

3. 以上说的变量都是在全局的情况下  如果是局部变量  和全局变量同名 不会出错 按照变量的作用范围判断到底用哪个,但是不建议这种全局与局部同名的方法  很容易出逻辑错误

 

 

 

下面附上关于本节内容解释的较好的博客

https://blog.csdn.net/gui1259802368/article/details/68947724

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值