When I declared and initialized a const object.
// ConstClass.h
class ConstClass
{
};
const ConstClass g_Const;
And two cpp files include this header.
// Unit1.cpp
#include "ConstClass.h"
#include "stdio.h"
void PrintInUnit1( )
{
printf( "g_Const in Unit1 is %d.\r\n", &g_Const );
}
and
// Unit2.cpp
#include "ConstClass.h"
#include "stdio.h"
void PrintInUnit2( )
{
printf( "g_Const in Unit2 is %d.\r\n", &g_Const );
}
When i build the solution, there was no link error, what you will get If g_Const is a non-const fundamental type!
And PrintInUnit1() and PrintInUnit2() show that there are two independent "g_Const"s with different address in two compilation units, Why?
==============
I know how to fix it.(use extern keyword to declaration, and define it in one cpp file.)
I wonder to know why I did't get redfined link error in this sample.
https://stackoverflow.com/a/6173889/1508519
const variable at namespace scope has internal linkage. So they're basically two different variables. There is no redefinition.
3.5/3 [basic.link]:
A name having namespace scope (3.3.5) has internal linkage if it is the name of
— an object, reference, function or function template that is explicitly declared static or,
— an object or reference that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage; or
— a data member of an anonymous union.
Use extern
if you want it to have external linkage.
As stated in the other answer, header files are just pasted in cpp files. The same header file is included in both cpp files, but they are separate translation units . That means that one instance of a variable is different from the other instance. In other to let the compiler know that you have defined the variable elsewhere, use the extern
keyword. This ensures only one instance is shared across translation units. However extern const Test test
is just a declaration. You need a definition. It doesn't matter where you define it as long as it is defined once in some cpp file. You can declare it as many times as you want (which is convenient for placing it in a header file.)
So for example:
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
Because you put variable definition in header file. Including header file is just like replacing it with the content of the file. So, the first file:
// 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 );
}
will become (after preprocessing phase before compiling):
// 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 );
}
And the second file will be:
// 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 );
}
As you can see, each file has separate variable g_Const
(this is just for the case of your code in here, there maybe no variable at all just like macro, see explanation in my last paragraph).
If what you want is not the definition of the variable just the declaration in the header file, you should use extern
keyword in the header file:
extern const ConstClass g_Const;
Then you can put the definition of g_Const
variable in ConstClass.c
There is some catch in your code:
g_Const
definition, you must assign it a constant value in the definition unless you want the default value (0). const
variable of C++. This actually force the compiler to create the variable in stack. If you don't take the address it may be able to infer a compile time number behaving like macro in C (you can get the magic number directly put in the code where you use the const
variable).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.