在C ++中全局初始化类的正确方法

问题描述 投票:2回答:5

我知道global是不好的,但作为一种实践,这是初始化在多个目标文件之间使用的global类的正确方法吗?

Header 1.h

class test {
 int id;
 public:
 test(int in){
   id = in;
 }
 int getId(){
  return id;
 }
};

extern test t;

文件1.cc

#include <iostream>
#include "1.h"

int main(){
 std::cout << t.getId() << std::endl;
 return 0;
}

文件2.cc:

#include "1.h"

test t(5);

现在,如果我在标题中全局使用extern而不是static,该怎么办?

如果我错了,请更正我,但是可以很好地编译,但是在目标文件和最终二进制文件中,我将具有相同static test t(0);的2个不同的不相关副本?那不好吗?还是链接程序将其整理出来以消除多个副本?

c++ static initialization one-definition-rule
5个回答
5
投票

有全局实例,而不是全局类。

您拥有的是一个全局实例。是的,这听起来很对,直到您获得了相互依赖的多个全局实例。然后,真正的乐趣就会开始。


1
投票

在全局级别将变量定义为'static'意味着该变量将仅在编译单元中定义(即'o'文件),并且链接器不会导出该符号。

换句话说:是的,将有多个具有相同名称的变量,但仅对同一编译单元上的函数可见。

此外,这里的“隐形”并不意味着“无法进入”。您仍然可以提供对变量的访问。例如:

1.h

t

1.cc

struct Test { int value; };         // Class definition
Test& get_test();                   // Function declaration

2.cc

#include "1.h"
static Test t;                      // Variable declared as 'static'
Test& get_t() { return t; };

0
投票

我全局使用静态方法#include "1.h" #include <iostream> int main() { std::cout << get_t().value << std::endl; // Static variable accessed }

但是您的static test t; test需要构造函数的class参数,因此您需要:

int in

0
投票

如果将标题中的static test t(0); // or whatever int you want 转换为extern,则将在每个要导入标题的编译单元中定义一个static变量。因此,不同的cpp文件中的类将不再通过t“通信”,因为每个类都有它们。这非常容易出错。

此外,在static中添加static的定义为header。当有人包含标头时,不会期望它会创建变量。

[将an extremely bad practice声明为t是可接受的做法。但是请注意,如果标头具有通用用途,则可能会降低其在其他项目中的可重用性。

您感兴趣的更多信息:


0
投票

如果将变量声明放在任何函数之外,则将变量声明为'global'。例如:

1.cc

Why global variables should be avoided if possible and when are they ok

从这里开始,您可以在'1.cc'的任何函数中使用该变量。

对于在任何其他文件中使用相同的变量,编译器将需要了解它:

2.cc

int this_is_global;

这里,关键字extern int this_is_global; 告诉编译器该变量已声明为其他地方,让查找它的任务交给链接器。

如果您想在此处添加extern关键字,则编译器会将其视为新变量,并且链接器将具有两个具有相同名称的变量,并且将发出错误。您的项目第一个除外的所有源文件都需要extern关键字,以避免重复的符号。

所以通常的做法是将'extern'声明添加到包含文件中:

1.cc

extern

1.h

int this_is_global;

2.cc

extern int this_is_global;

另一方面,关键字#include "1.h" 告诉编译器不执行导出符号。换句话说:该变量仅存在于声明的源文件中。您可以为每个源文件声明一次,并且会有相同名称的不同变量。例如:

1.h

static

1.cc

static int my_var;

2.cc

#include "1.h"

这样,您将最终拥有两个变量“ my_var”,对其中任何一个的更改都不会影响另一个。

© www.soinside.com 2019 - 2024. All rights reserved.