65,209
社区成员
发帖
与我相关
我的任务
分享
[/quote]
在同一处编译,只会有一个实例化的版本,但是在不同地方编译,可以出现多份实例
另外,有些编译器可能有办法解决这个问题。
同一程序,编译成多个.obj或者.lib 这是很正常的现象;
然后把这些.obj,.lib链接成一个程序。
这样就会出现一个模板有两份实现的现象了。
[/quote]
你的 答案 ,我请教了几个前辈了
他们说,如果特殊情况下,递归定义也会出现问题
//主程序:
#include <iostream>
#include <string>
template< typename T>
class Tester
{
public:
T Member();
virtual T VirtualMember();
static T StaticMember();
};
Tester<std::string> * GetTester1();
Tester<std::string> * GetTester2();
void Test1();
void Test2();
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "\nCall Test1:\n";
Test1();
std::cout << "\nCall Test2:\n";
Test2();
std::cout << "\nCall GetTester1:\n";
Tester<std::string> * t = GetTester1();
t->Member();
t->VirtualMember();
t->StaticMember();
std::cout << "\nCall GetTester2:\n";
t = GetTester2();
t->Member();
t->VirtualMember();
t->StaticMember();
return 0;
}
//运行结果:
Call Test1:
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Call Test2:
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Call GetTester1:
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Call GetTester2:
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
:
//test1.cpp:
#include <iostream>
#include <string>
template< typename T>
class Tester
{
public:
T Member();
virtual T VirtualMember();
static T StaticMember();
};
template <typename T>
T Tester<T>::Member()
{
static T nothing;
std::cout << "Tester::Member() in Test1.cpp\n";
return nothing;
}
template <typename T>
T Tester<T>::VirtualMember()
{
static T nothing;
std::cout << "Tester::Member() in Test1.cpp\n";
return nothing;
}
template <typename T>
T Tester<T>::StaticMember()
{
static T nothing;
std::cout << "Tester::Member() in Test1.cpp\n";
return nothing;
}
Tester<std::string> * GetTester1()
{
return new Tester<std::string>;
}
void Test1()
{
Tester<std::string> t;
t.Member();
t.VirtualMember();
t.StaticMember();
}
//Test2.cpp
#include <iostream>
#include <string>
template< typename T>
class Tester
{
public:
T Member();
virtual T VirtualMember();
static T StaticMember();
};
template <typename T>
T Tester<T>::Member()
{
static T nothing;
std::cout << "Tester::Member() in Test2.cpp\n";
return nothing;
}
template <typename T>
T Tester<T>::VirtualMember()
{
static T nothing;
std::cout << "Tester::Member() in Test2.cpp\n";
return nothing;
}
template <typename T>
T Tester<T>::StaticMember()
{
static T nothing;
std::cout << "Tester::Member() in Test2.cpp\n";
return nothing;
}
Tester<std::string> * GetTester2()
{
return new Tester<std::string>;
}
void Test2()
{
Tester<std::string> t;
t.Member();
t.VirtualMember();
t.StaticMember();
}
//主程序:
#include <iostream>
#include <string>
template< typename T>
class Tester
{
public:
T Member();
virtual T VirtualMember();
static T StaticMember();
};
Tester<std::string> * GetTester1();
Tester<std::string> * GetTester2();
void Test1();
void Test2();
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "\nCall Test1:\n";
Test1();
std::cout << "\nCall Test2:\n";
Test2();
std::cout << "\nCall GetTester1:\n";
Tester<std::string> * t = GetTester1();
t->Member();
t->VirtualMember();
t->StaticMember();
std::cout << "\nCall GetTester1:\n";
t = GetTester1();
t->Member();
t->VirtualMember();
t->StaticMember();
return 0;
}
//运行结果:
Call Test1:
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Call Test2:
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Call GetTester1:
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Call GetTester1:
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
Tester::Member() in Test1.cpp
所以,大家如果要写一个只在某一个cpp文件中使用的“辅助类”,一定不要忘记把它们放在匿名namespace中,不要以为只放在cpp中就不会被别人使用,要当心因为重名而被合并。上面的代码中,如果在test1.cpp和test2.cpp中把类声明及定义都放在匿名namespace中,就会出现链接错误。
[/quote]
在同一处编译,只会有一个实例化的版本,但是在不同地方编译,可以出现多份实例
另外,有些编译器可能有办法解决这个问题。
同一程序,编译成多个.obj或者.lib 这是很正常的现象;
然后把这些.obj,.lib链接成一个程序。
这样就会出现一个模板有两份实现的现象了。
[/quote]
我试了下,在vs2005中,在不同的的编译单元中,也是一份,我让朋友在gcc4.3中试了下,也一样
#pragma once
#include <stdio.h>
template<typename T>
class Test
{
public:
static T val;
public:
static void Fun(){}
static void show(){
printf("%x\n",&val);
}
void Fun2(){}
};
template<typename T>
T Test<T>::val=1
放在不同的文件中编译,调用,打印出的地址,都是一样,
[/quote]
在同一处编译,只会有一个实例化的版本,但是在不同地方编译,可以出现多份实例
另外,有些编译器可能有办法解决这个问题。
同一程序,编译成多个.obj或者.lib 这是很正常的现象;
然后把这些.obj,.lib链接成一个程序。
这样就会出现一个模板有两份实现的现象了。

ExampleSingleton second( ExampleSingleton::Instance());
Singleton<ExampleSingleton> third(ExampleSingleton::Instance());
因此,应该在Singleton的声明中加上:
private:
Singleton( Singleton<T> const & );
