免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3157 | 回复: 6
打印 上一主题 下一主题

[C++] 求助:类模板初始化问题(已解决) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-10 14:24 |只看该作者 |倒序浏览
问题已经解决了,在类模板头文件添加模板泛化申明就可以了。
感谢FuriousFive 和 tyc611  的帮助
感谢大家的关注。


///谁来帮帮我吧!搞了两天了没有搞定
///在singleton.h定义了如下模板


template< class T >
class Singleton
{
      class InstanceHolder
    {
    public:
        InstanceHolder() : mObject(0) {}
        ~InstanceHolder() { delete mObject; }
        T* get() { return mObject; }
        void set(T* p) { delete mObject; mObject = p; }

    private:
         InstanceHolder(const InstanceHolder&);
        InstanceHolder& operator=(const InstanceHolder&);

    private:
          T* mObject;
    };

public:
      static T* instance()
    {
        if (!mFlag)
        {
            pthread_mutex_lock(&mMutex);
            if (!mFlag)
            {
                mInstance.set(new T());
                mFlag = 1;
            }
          pthread_mutex_unlock(&mMutex);
         }
        return mInstance.get();
    }

private:
       static InstanceHolder             mInstance;
        static volatile sig_atomic_t    mFlag;
    static pthread_mutex_t          mMutex;

       Singleton();
       Singleton(const Singleton&);

     Singleton& operator=(const Singleton&);
};
///////////////////////////////////////////////////////////////
/*
*在头文件singleton.h最后把类模板中mInstance进行泛化就可以了,这样应用的.cc文件才能找到链接申明
*/
template<typename T> typename Singleton<T>::InstanceHolder Singleton<T>::mInstance;
/////////////////////////////////////////////////////////////


///在APP.h中定义了

typedef Singleton<ServiceController> ServiceKontrol;

class ServiceController : public ServiceListener
{
public:
        ServiceController();
        ~ServiceController();

        int init();
                int run();
        int start();
        int stop();
}


////在APP.cc中引用前需要声明和初始化 mInstance mFlag mMutex
///fedora 4/gcc-3.2.3下声明和初始化如下,编译链接都没有问题
ServiceKontrol::InstanceHolder ServiceKontrol::mInstance;       
volatile sig_atomic_t          ServiceKontrol::mFlag = 0;
pthread_mutex_t                ServiceKontrol::mMutex;
int
ServiceController::run()
{
}


///代码移植到Fedora 6、gcc4.1.1,修改成如下,编译可以通过,在使用g++链接的时候出现Error
template<> ServiceKontrol::InstanceHolder ServiceKontrol::mInstance;        //这个小弟不知道该怎么初始化?????
                                                  ////在连接的时候出现singleton.h:90: undefined reference to `Singleton<ServiceController>::mInstance'
template<> volatile sig_atomic_t                   ServiceKontrol::mFlag   = 0;
template<> pthread_mutex_t                           ServiceKontrol::mMutex = PTHREAD_MUTEX_INITIALIZER;
int
ServiceController::run()
{
}

[ 本帖最后由 xgdyyf11071 于 2008-12-11 16:03 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-12-10 14:35 |只看该作者
原帖由 xgdyyf11071 于 2008-12-10 14:24 发表
///在singleton.h定义了如下模板
///
template< class T >
class Singleton
{
      class InstanceHolder
    {
    public:
        InstanceHolder() : mObject(0) {}
        ~InstanceHolder() { ...


补充一下,编译平台是Fedora 6 gcc-4.1.1

论坛徽章:
0
3 [报告]
发表于 2008-12-10 16:13 |只看该作者
我也不清楚,本来认为应该这么写
template<class T> Singleton<T>::InstanceHolder Singleton<T>::mInstance ;
但是也编译不过

论坛徽章:
0
4 [报告]
发表于 2008-12-10 16:40 |只看该作者

回复 #3 FuriousFive 的帖子

谢谢 FuriousFive 的回复!
你的这个写法我已经试过了的,其实这个写法和我上面那个是一样的,只不过我在APP.h里面做了一下
typedef Singleton<ServiceController> ServiceKontrol;

论坛徽章:
0
5 [报告]
发表于 2008-12-10 16:58 |只看该作者
问题解决了
template<class T> Singleton<T>::InstanceHolder Singleton<T>::mInstance ;
需要加一个typename
template<class T> typename Singleton<T>::InstanceHolder Singleton<T>::mInstance ;
我这么写就通过了

论坛徽章:
0
6 [报告]
发表于 2008-12-10 17:17 |只看该作者

回复 #5 FuriousFive 的帖子

FuriousFive ,您好
我的问题还是没有解决,
我把我的代码简化了一下,可不可以在帮我看看
//test.cc
#include <stdio.h>
using namespace std;
template< class T >
class Singleton
{
    class InstanceHolder
    {
    public:
        InstanceHolder() : mObject(0) {}
        ~InstanceHolder() { delete mObject; }

        void set(T* p) { delete mObject; mObject = p; }
    private:
        T* mObject;
    };

public:
    static T* instance()
    {
        return mInstance.set(new T());
    }

private:
    static InstanceHolder             mInstance;
    Singleton();
};

class        ServiceListener
{
public:
        virtual ~ServiceListener()
        { }
        virtual void serviceStarted() = 0;
        virtual void serviceStopped() = 0;
};
void ServiceListener::serviceStarted()
{
        printf("serviceStarted() event listener is not implemented.");
}

void ServiceListener::serviceStopped()
{
        printf("serviceStarted() event listener is not implemented.");
}

class ServiceController;

typedef Singleton<ServiceController> ServiceKontrol;

class ServiceController : public ServiceListener
{
public:
        ServiceController();
        ~ServiceController();

        virtual void serviceStarted();
        virtual void serviceStopped();

private:
        bool started;
};

ServiceController::ServiceController() : started(false)
{
}

ServiceController::~ServiceController()
{
}


void
ServiceController::serviceStarted()
{
        printf("service start\n");
}

void
ServiceController::serviceStopped()
{
        printf("servicestop\n");
}


template<class T> typename ServiceKontrol::InstanceHolder ServiceKontrol::mInstance;

int main(int argc, char **argv)
{
        ServiceKontrol::instance()->serviceStarted();
        //ServiceController a;
        //a.serviceStarted();
        return 0;
}


[root@localhost flashdisk]# g++ -o test.o test.cc
test.cc: In static member function static T* Singleton<T>::instance() [with T = ServiceController]鈥?
test.cc:20:   instantiated from singleton<ServiceController>::InstanceHolder Singleton<ServiceController>::mInstance鈥?
test.cc:20:   instantiated from static T* Singleton<T>::instance() [with T = ServiceController]鈥?
test.cc:89:   instantiated from here
test.cc:20: internal compiler error: in instantiate_decl, at cp/pt.c:11906
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://bugzilla.redhat.com/bugzilla> for instructions.
Preprocessed source stored into /tmp/ccHFDXCH.out file, please attach this to your bugreport.
[root@localhost flashdisk]#

[ 本帖最后由 xgdyyf11071 于 2008-12-10 17:46 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2008-12-10 18:54 |只看该作者

回复 #1 xgdyyf11071 的帖子

在Instance类后加上这个:
template< class T >
typename Singleton<T>::InstanceHolder Singleton<T>::mInstance;
后面的mInstance定义就不要了


或者改为:
template<>
ServiceKontrol::InstanceHolder ServiceKontrol::mInstance;

[ 本帖最后由 tyc611 于 2008-12-10 18:57 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP