栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 链接时出现多重定义问题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 链接时出现多重定义问题

我好像一直以来都以为编译链接的时候,在头文件里用了条件编译#ifndef #define #endif或pragma once就不会出现multiple definition of xx的问题,直到昨天…
情形如下,我在头文件里定义了一个函数而不是声明,然后两个cpp文件都include了这个头文件,最后链接的时候就出现了以上问题。因为对编译的理解不够才导致了这个问题。
头文件如下:

#ifndef HEADER_H
#define HEADER_H

#include 
#include 
using namespace std;
void print(string &message) { cout << message << endl; }

#endif

cpp1如下:

#include "header.h"

void fun() { print("hello world"); }

main.cpp如下:

#include "header.h"

extern void fun();
int main() { 
 fun();
 return 0;
}

编译器每次编译一个文件时都会把include的头文件包括进来,所以在编译cpp1时,会定义一个print的函数;在编译main时,又定义一个print的函数,其实这时还没有产生错误。当我们链接这两个编译后的文件之后,才产生了多次定义错误。根据下图也能看到是链接器报错。


为什么fun函数没有报错?
因为在main里我是声明了fun函数,在编译时编译器就知道别处有这样一个函数,在链接的时候看到cpp1里定义了fun函数,于是把main的fun符号重定位到cpp1的fun函数,所以最后调用的是cpp1定义的fun函数(这里链接时链接器是如何做的我不是很清楚)

头文件被包含多次时tips:

  1. 用const修饰的变量会默认对其他cpp文件不可见,所以在头文件里定义了const int a = 1并多次包含这个头文件不会保错。
  2. 对于类来说,似乎写在头文件class x{};括号里的内容都不产生这种错误。如下:
#ifndef HEADER_H
#define HEADER_H

#include 
#include 
using namespace std;
class A {
    void print(){} //no error
};
#endif

如果定义在类外同时在头文件中,会产生错误。如下:

#ifndef HEADER_H
#define HEADER_H

#include 
#include 
using namespace std;
class A {
    void print();
};
void A::print(){} //error
#endif
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/847017.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号