关于模板类中的静态成员变量和静态函数疑问?

wahaha_1986 2014-01-13 10:40:36
1.一般类中的静态成员变量是属于类的,数据放在静态变量区,所有类实例共用该静态变量。但是模板类的静态变量就不一样,模板实例化一次就产生一个新的类,所以设想模板类中的静态变量应该是属于实例化类的,模板被实例化N次就会在静态变量区产生N个静态变量。

2.一般类的静态成员函数也是属于类的,函数入口地址提供给所有类实例对象共用,但是模板类呢?
写代码测试:
“test.h”如下:
#include "stdafx.h"

template<typename Type>
class CBase
{
public:
int static GetI();
public:
static int m_i;

};
“test.cpp”如下:
#include "stdafx.h"
#include "test.h"

template<class Type>
int CBase<Type>::m_i = 100;

template<class Type>
int CBase<Type>::GetI()
{
return m_i;
}
“main()”如下:
#include "stdafx.h"
#include "test.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
cout << &CBase<int>::m_i << endl;
cout << CBase<int>::GetI << endl;

cout << &CBase<double>::m_i << endl;
cout << CBase<double>::GetI << endl;

return 0;
}
但是存在链接错误,求指点:



...全文
153 1 收藏 9
写回复
9 条回复
金丝龙麟闪电劈 2014年01月13日
http://blog.csdn.net/pongba/article/details/19130 为什么C++编译器不能支持对模板的分离式编译
回复 点赞
金丝龙麟闪电劈 2014年01月13日
在分离式编译的环境下,编译器编译某一个.cpp文件时并不知道另一个.cpp文件的存在,也不会去查找(当遇到未决符号时它会寄希望于连接器)。这种模式在没有模板的情况下运行良好,但遇到模板时就傻眼了,因为模板仅在需要的时候才会实例化出来,所以,当编译器只看到模板的声明时,它不能实例化该模板,只能创建一个具有外部连接的符号并期待连接器能够将符号的地址决议出来。然而当实现该模板的.cpp文件中没有用到模板的实例时,编译器懒得去实例化,所以,整个工程的.obj中就找不到一行模板实例的二进制代码,于是连接器也黔驴技穷了。
回复 点赞
漫步者、 2014年01月13日
引用 3 楼 wahaha_1986 的回复:
[quote=引用 2 楼 ganpengjin1 的回复:] 你是用的什么编译器,我这里没有问题
我用的是VS2008[/quote] 模板的实现不能它的定义分开的。分开的模式很少有编译器支持
回复 点赞
wahaha_1986 2014年01月13日
引用 1 楼 ALNG 的回复:
在vs2013 express中编译通过了。只是放在一起了而已。我用的


template<typename Type>
class CBase
{
public:
	int static GetI();
public:
	static int m_i;

};

template<class Type>
int CBase<Type>::m_i = 100;

template<class Type>
int CBase<Type>::GetI()
{
	return m_i;
}

#include <iostream>
using namespace std;

int main()
{
	cout << &CBase<int>::m_i << endl;
	cout << CBase<int>::GetI << endl;
	
	cout << &CBase<double>::m_i << endl;
	cout << CBase<double>::GetI << endl;
	
	return 0;
}
输出4个不同的地址。
谢谢你的答案,我用的是VS2008,我合并起来试一试。
回复 点赞
AndyStevens 2014年01月13日
不要用分离模型哦,否则不显式实例化的话会链接不到模板的定义的。 把main()上面的#include "test.h" 改成 #include "test.cpp"
回复 点赞
wahaha_1986 2014年01月13日
引用 2 楼 ganpengjin1 的回复:
你是用的什么编译器,我这里没有问题
我用的是VS2008
回复 点赞
漫步者、 2014年01月13日
你是用的什么编译器,我这里没有问题
回复 点赞
孩皮妞野 2014年01月13日
在vs2013 express中编译通过了。只是放在一起了而已。我用的


template<typename Type>
class CBase
{
public:
	int static GetI();
public:
	static int m_i;

};

template<class Type>
int CBase<Type>::m_i = 100;

template<class Type>
int CBase<Type>::GetI()
{
	return m_i;
}

#include <iostream>
using namespace std;

int main()
{
	cout << &CBase<int>::m_i << endl;
	cout << CBase<int>::GetI << endl;
	
	cout << &CBase<double>::m_i << endl;
	cout << CBase<double>::GetI << endl;
	
	return 0;
}
输出4个不同的地址。
回复 点赞
wahaha_1986 2014年01月13日
谢谢各位热心回答,结贴给分了哈。
回复 点赞
发动态
发帖子
C++ 语言
创建于2007-09-28

3.1w+

社区成员

24.8w+

社区内容

C++ 语言相关问题讨论,技术干货分享
社区公告
暂无公告