类的静态成员的初始化和全局变量的初始化问题

时间:2021-11-02 19:45:11
1,一个类的静态成员是在头文件里面初始比较好还是在类的实现里面比较好呢?假设类由头文件定义,由cpp文件实现;
2,全局变量也一样,就是在一个类文件里面,是在头文件中声明、定义好,还是在类的实现文件中声明定义,然后在类的头文件中在另外声明一下;
3,我们编程时候常常会用到include,请问编译器是如何处理的啊
谢谢大侠们哦

11 个解决方案

#1


1,一个类的静态成员是在头文件里面初始比较好还是在类的实现里面比较好呢?假设类由头文件定义,由cpp文件实现;
2,全局变量也一样,就是在一个类文件里面,是在头文件中声明、定义好,还是在类的实现文件中声明定义,然后在类的头文件中在另外声明一下;

我认为都不能绝对的讲那个好或坏的。

在类里面定义变量的时候,不可以直接对其初始化。含有静态成员变量的类在类定义时仅仅是声明了存在这样一个变量


3,我们编程时候常常会用到include,请问编译器是如何处理的啊

首先include是C++中的一个语言,包含头文件的。
编译器是如何处理的,我觉得可能就是展开调用吧。

#2


1,一个类的静态成员是在头文件里面初始比较好还是在类的实现里面比较好呢?假设类由头文件定义,由cpp文件实现;

这个根据具体需要,静态成员不是为一个对象服务。我喜欢把他放在头文件里

2,全局变量也一样,就是在一个类文件里面,是在头文件中声明、定义好,还是在类的实现文件中声明定义,然后在类的头文件中在另外声明一下;

全局放在头文件里。以 extren 声明,方便多个CPP文件访问;

3,我们编程时候常常会用到include,请问编译器是如何处理的啊

#include"stdio.h" #include<math.h> 但是这两种形式是有区别的:使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的), 而不在源文件目录去查找; 使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中去查找。 用户编程时可根据自己文件所在的目录来选择某一种命令形式。

#3


mark

#4


1,一个类的静态成员是在头文件里面初始比较好还是在类的实现里面比较好呢?假设类由头文件定义,由cpp文件实现;
2,全局变量也一样,就是在一个类文件里面,是在头文件中声明、定义好,还是在类的实现文件中声明定义,然后在类的头文件中在另外声明一下;
3,我们编程时候常常会用到include,请问编译器是如何处理的啊
___________________________________________________________________________________
我之说我自己认为的观点:
1,2,一般情况下我都是将静态成员作为局部变量所以没有在哪里初始化好的问题,全局变量我一般 很少用或者几乎不用.
3,在大部分的C++编译器里面以#开头的都是编译预处理命令,#include它的主要功能是告诉预处理程序在这里需要插入一个文件当中的代码,如果程序过大的话,可能会出现重复插入的现象,可以通过使用条件编译命令.你可以看刘jing的书,高教出版社,或者上网上搜。

#5


我以前同说过类的静态变量在不同地方初始化对程序有影响的。
还有,第三个问题我是想知道include和编译器的link之间的关系
谢谢

#6


1,一个类的静态成员是在头文件里面初始比较好还是在类的实现里面比较好呢?假设类由头文件定义,由cpp文件实现;
2,全局变量也一样,就是在一个类文件里面,是在头文件中声明、定义好,还是在类的实现文件中声明定义,然后在类的头文件中在另外声明一下;

答案都一样:在类的实现里面比较好, 举个例子, 一个工程中包含了以下三个文件, 结果是会出错的.

//a.h
#ifndef A_H
#define A_H
class A
{
static int i;
};
A::i=0;
#endif


//b.h
#include "a.h"

//c.h
#include "a.h"

3,我们编程时候常常会用到include,请问编译器是如何处理的啊
编译器就是include的指示读取相应的文件的内容.

#7


1,一个类的静态成员是在头文件里面初始比较好还是在类的实现里面比较好呢?假设类由头文件定义,由cpp文件实现;
2,全局变量也一样,就是在一个类文件里面,是在头文件中声明、定义好,还是在类的实现文件中声明定义,然后在类的头文件中在另外声明一下;

答案都一样:在类的实现里面比较好, 举个例子, 一个工程中包含了以下三个文件, 结果是会出错的.

//a.h
#ifndef A_H
#define A_H
class A
{
static int i;
};
int A::i=0;
#endif


//b.h
#include "a.h"

//c.h
#include "a.h"

3,我们编程时候常常会用到include,请问编译器是如何处理的啊
编译器就是include的指示读取相应的文件的内容.

#8


因为普通静态数据具有static linkage——静态链接属性,

因此将一个static数据定义到头文件中,然后被多个源文件

使用是没有问题的,比如(以下使用vc的cl.exe):

// foo.h
static int i = 47;

// foo.cpp
#include <iostream>
#include "foo.h"
using namespace std;

void f();
int main() {
cout << "foo: " << i << endl;
i++;
f();
return 0;
}


// bar.cpp
#include <iostream>
#include "foo.h"
using namespace std;

void f() { cout << "bar: " << i << endl; }


当foo.obj + bar.obj => foo.exe被执行之后,结果输出:

foo: 47
bar: 47

说明两个obj中存在了两个互不干涉的静态成员i。

但是对于静态的成员变量,

// foo.h

class X {
public:
static int i;
};

int X::i = 47;


// foo.cpp
#include <iostream>
#include "foo.h"
using namespace std;

void f();
int main() {
cout << "foo: " << X::i << endl;
X::i++;
f();
return 0;
}

// bar.cpp
#include <iostream>
#include "foo.h"
using namespace std;

void f() { cout << "bar: " << X::i << endl; }

在compile-time一切正常,foo.cpp -> foo.obj, bar.cpp -> bar.obj

但是当我link它们的时候,出现了:

/out:foo.exe
foo.obj
bar.obj
bar.obj : error LNK2005: "public: static int  X::i" (?i@X@@2HA) already defined
in foo.obj
foo.exe : fatal error LNK1169: one or more multiply defined symbols found

显然出现了符号重复定义的错误。因此对于类的静态成员来说,他们不具有局部连结属性。

这样,当我把定义放到源文件当中后:

#include <iostream>
#include "foo.h"
using namespace std;

int X::i = 47; // !!!
void f();
int main() {
cout << "foo: " << X::i << endl;
X::i++;
f();
return 0;
}

link结果:

/out:foo.exe
foo.obj
bar.obj

OK,一切正常。因此对于普通静态数据来说可以放到header中,而对类静态成员

成员来说,应该把它放到源文件中。


对于#include,编译器在开始编译之前会有preprocessor——预编译处理器

控制局面,它会把#include后面的文件加到当前的位置上,一切处理妥当后,

把控制交给compiler来处理。

#9


在CPP中初始,别人用H文件的时候,不能修改这些变量
#include 编译器去查找文件,然后加载到当前

#10


谢谢大家的回答

但是全局变量实在.h中定义,.cpp文件中申明一下还是在.cpp中定义,在.h中申明比较好呢?

谢谢

#11


全局变量必须在cpp文件中定义,加一个extern在.h中声明。

#1


1,一个类的静态成员是在头文件里面初始比较好还是在类的实现里面比较好呢?假设类由头文件定义,由cpp文件实现;
2,全局变量也一样,就是在一个类文件里面,是在头文件中声明、定义好,还是在类的实现文件中声明定义,然后在类的头文件中在另外声明一下;

我认为都不能绝对的讲那个好或坏的。

在类里面定义变量的时候,不可以直接对其初始化。含有静态成员变量的类在类定义时仅仅是声明了存在这样一个变量


3,我们编程时候常常会用到include,请问编译器是如何处理的啊

首先include是C++中的一个语言,包含头文件的。
编译器是如何处理的,我觉得可能就是展开调用吧。

#2


1,一个类的静态成员是在头文件里面初始比较好还是在类的实现里面比较好呢?假设类由头文件定义,由cpp文件实现;

这个根据具体需要,静态成员不是为一个对象服务。我喜欢把他放在头文件里

2,全局变量也一样,就是在一个类文件里面,是在头文件中声明、定义好,还是在类的实现文件中声明定义,然后在类的头文件中在另外声明一下;

全局放在头文件里。以 extren 声明,方便多个CPP文件访问;

3,我们编程时候常常会用到include,请问编译器是如何处理的啊

#include"stdio.h" #include<math.h> 但是这两种形式是有区别的:使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的), 而不在源文件目录去查找; 使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中去查找。 用户编程时可根据自己文件所在的目录来选择某一种命令形式。

#3


mark

#4


1,一个类的静态成员是在头文件里面初始比较好还是在类的实现里面比较好呢?假设类由头文件定义,由cpp文件实现;
2,全局变量也一样,就是在一个类文件里面,是在头文件中声明、定义好,还是在类的实现文件中声明定义,然后在类的头文件中在另外声明一下;
3,我们编程时候常常会用到include,请问编译器是如何处理的啊
___________________________________________________________________________________
我之说我自己认为的观点:
1,2,一般情况下我都是将静态成员作为局部变量所以没有在哪里初始化好的问题,全局变量我一般 很少用或者几乎不用.
3,在大部分的C++编译器里面以#开头的都是编译预处理命令,#include它的主要功能是告诉预处理程序在这里需要插入一个文件当中的代码,如果程序过大的话,可能会出现重复插入的现象,可以通过使用条件编译命令.你可以看刘jing的书,高教出版社,或者上网上搜。

#5


我以前同说过类的静态变量在不同地方初始化对程序有影响的。
还有,第三个问题我是想知道include和编译器的link之间的关系
谢谢

#6


1,一个类的静态成员是在头文件里面初始比较好还是在类的实现里面比较好呢?假设类由头文件定义,由cpp文件实现;
2,全局变量也一样,就是在一个类文件里面,是在头文件中声明、定义好,还是在类的实现文件中声明定义,然后在类的头文件中在另外声明一下;

答案都一样:在类的实现里面比较好, 举个例子, 一个工程中包含了以下三个文件, 结果是会出错的.

//a.h
#ifndef A_H
#define A_H
class A
{
static int i;
};
A::i=0;
#endif


//b.h
#include "a.h"

//c.h
#include "a.h"

3,我们编程时候常常会用到include,请问编译器是如何处理的啊
编译器就是include的指示读取相应的文件的内容.

#7


1,一个类的静态成员是在头文件里面初始比较好还是在类的实现里面比较好呢?假设类由头文件定义,由cpp文件实现;
2,全局变量也一样,就是在一个类文件里面,是在头文件中声明、定义好,还是在类的实现文件中声明定义,然后在类的头文件中在另外声明一下;

答案都一样:在类的实现里面比较好, 举个例子, 一个工程中包含了以下三个文件, 结果是会出错的.

//a.h
#ifndef A_H
#define A_H
class A
{
static int i;
};
int A::i=0;
#endif


//b.h
#include "a.h"

//c.h
#include "a.h"

3,我们编程时候常常会用到include,请问编译器是如何处理的啊
编译器就是include的指示读取相应的文件的内容.

#8


因为普通静态数据具有static linkage——静态链接属性,

因此将一个static数据定义到头文件中,然后被多个源文件

使用是没有问题的,比如(以下使用vc的cl.exe):

// foo.h
static int i = 47;

// foo.cpp
#include <iostream>
#include "foo.h"
using namespace std;

void f();
int main() {
cout << "foo: " << i << endl;
i++;
f();
return 0;
}


// bar.cpp
#include <iostream>
#include "foo.h"
using namespace std;

void f() { cout << "bar: " << i << endl; }


当foo.obj + bar.obj => foo.exe被执行之后,结果输出:

foo: 47
bar: 47

说明两个obj中存在了两个互不干涉的静态成员i。

但是对于静态的成员变量,

// foo.h

class X {
public:
static int i;
};

int X::i = 47;


// foo.cpp
#include <iostream>
#include "foo.h"
using namespace std;

void f();
int main() {
cout << "foo: " << X::i << endl;
X::i++;
f();
return 0;
}

// bar.cpp
#include <iostream>
#include "foo.h"
using namespace std;

void f() { cout << "bar: " << X::i << endl; }

在compile-time一切正常,foo.cpp -> foo.obj, bar.cpp -> bar.obj

但是当我link它们的时候,出现了:

/out:foo.exe
foo.obj
bar.obj
bar.obj : error LNK2005: "public: static int  X::i" (?i@X@@2HA) already defined
in foo.obj
foo.exe : fatal error LNK1169: one or more multiply defined symbols found

显然出现了符号重复定义的错误。因此对于类的静态成员来说,他们不具有局部连结属性。

这样,当我把定义放到源文件当中后:

#include <iostream>
#include "foo.h"
using namespace std;

int X::i = 47; // !!!
void f();
int main() {
cout << "foo: " << X::i << endl;
X::i++;
f();
return 0;
}

link结果:

/out:foo.exe
foo.obj
bar.obj

OK,一切正常。因此对于普通静态数据来说可以放到header中,而对类静态成员

成员来说,应该把它放到源文件中。


对于#include,编译器在开始编译之前会有preprocessor——预编译处理器

控制局面,它会把#include后面的文件加到当前的位置上,一切处理妥当后,

把控制交给compiler来处理。

#9


在CPP中初始,别人用H文件的时候,不能修改这些变量
#include 编译器去查找文件,然后加载到当前

#10


谢谢大家的回答

但是全局变量实在.h中定义,.cpp文件中申明一下还是在.cpp中定义,在.h中申明比较好呢?

谢谢

#11


全局变量必须在cpp文件中定义,加一个extern在.h中声明。