![](/img/trans.png)
[英]Using a global variable to initialize other global variable in different compilation units
[英]Global const object shared between compilation units
當我聲明並初始化一個const對象時。
// ConstClass.h
class ConstClass
{
};
const ConstClass g_Const;
兩個cpp文件包含此標頭。
// Unit1.cpp
#include "ConstClass.h"
#include "stdio.h"
void PrintInUnit1( )
{
printf( "g_Const in Unit1 is %d.\r\n", &g_Const );
}
和
// Unit2.cpp
#include "ConstClass.h"
#include "stdio.h"
void PrintInUnit2( )
{
printf( "g_Const in Unit2 is %d.\r\n", &g_Const );
}
當我構建解決方案時,沒有鏈接錯誤,你會得到什么如果g_Const是一個非const基本類型!
PrintInUnit1()和PrintInUnit2()表明在兩個編譯單元中有兩個獨立的“g_Const”具有不同的地址,為什么?
==============
我知道如何修復它。(使用extern關鍵字進行聲明,並在一個cpp文件中定義它。)
我想知道為什么我在這個示例中沒有得到redfined鏈接錯誤。
https://stackoverflow.com/a/6173889/1508519
命名空間范圍內的const變量具有內部鏈接。 所以它們基本上是兩個不同的變量。 沒有重新定義。
3.5 / 3 [basic.link]:
具有命名空間范圍(3.3.5)的名稱具有內部鏈接(如果它的名稱)
- 明確聲明為靜態的對象,引用,函數或函數模板,或
- 顯式聲明為const的對象或引用,既未顯式聲明為extern,也未聲明為具有外部鏈接; 要么
- 匿名聯盟的數據成員。
如果您希望它具有外部鏈接,請使用extern
。
如另一個答案所述,頭文件只是粘貼在cpp文件中。 兩個cpp文件中都包含相同的頭文件,但它們是單獨的轉換單元 。 這意味着變量的一個實例與另一個實例不同。 另一方面,讓編譯器知道您已在其他地方定義了變量,請使用extern
關鍵字。 這確保了翻譯單元之間只共享一個實例。 然而, extern const Test test
只是一個聲明。 你需要一個定義。 只要在某個cpp文件中定義了一次就定義它並不重要。 您可以根據需要多次聲明它(這樣可以方便地將其放在頭文件中。)
例如:
Constant.h
class Test
{
};
extern const Test test;
Unit1.cpp
#include "Constant.h"
#include <iostream>
void print_one()
{ std::cout << &test << std::endl; }
Unit2.cpp
#include "Constant.h"
#include <iostream>
void print_two()
{ std::cout << &test << std::endl; }
main.cpp中
extern void print_one();
extern void print_two();
int main()
{
print_one();
print_two();
}
Constant.cpp
#include "Constant.h"
const Test test = Test();
Makefile文件
.PHONY: all
all:
g++ -std=c++11 -o test Constant.cpp Unit1.cpp Unit2.cpp main.cpp
因為您將變量定義放在頭文件中。 包含頭文件就像用文件內容替換它一樣。 那么,第一個文件:
// Unit1.cpp
#include "ConstClass.h" // this will be replace with the content of ConstClass.h
#include "stdio.h"
void PrintInUnit1( )
{
printf( "g_Const in Unit1 is %d.\r\n", &g_Const );
}
將成為(在編譯之前的預處理階段):
// Unit1.cpp
// ConstClass.h
class ConstClass
{
};
const ConstClass g_Const;
//this line is replaced with the content of "stdio.h"
void PrintInUnit1( )
{
printf( "g_Const in Unit1 is %d.\r\n", &g_Const );
}
第二個文件將是:
// Unit2.cpp
// ConstClass.h
class ConstClass
{
};
const ConstClass g_Const;
//this line is replaced with the content of "stdio.h"
void PrintInUnit2( )
{
printf( "g_Const in Unit2 is %d.\r\n", &g_Const );
}
正如您所看到的,每個文件都有單獨的變量g_Const
(這只是針對您的代碼的情況,可能根本沒有像宏一樣的變量,請參閱我上一段中的解釋)。
如果你想要的不是變量的定義,而只是頭文件中的聲明,你應該在頭文件中使用extern
關鍵字:
extern const ConstClass g_Const;
然后,您可以將g_Const
變量的定義放在ConstClass.c
您的代碼中有一些問題:
g_Const
定義中沒有分配常量值,除非您需要默認值(0),否則必須在定義中為其分配一個常量值。 const
變量的地址。 這實際上迫使編譯器在堆棧中創建變量。 如果你不接受地址,它可能能夠推斷出在C中表現得像宏的編譯時間數(你可以直接將幻數放在你使用const
變量的代碼中)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.