lawala012
lawala012
采纳率50%
2015-11-29 12:42 浏览 2.2k

模板类构造函数与析构函数无法访问私有成员(明明就是公有的)

10

模板类构造函数与析构函数无法访问私有成员(明明就是公有的)

写成这样:

 #ifndef __SINGLETON__H__
#define __SINGLETON__H__

template <typename T>
class Worker;

template <typename T>
class Singleton
{
    friend class Worker<T>;
public:

    static T* GetInstance()
    {
        worker.i=3;
        /*worker.m_pInstance = new T();
        return worker.m_pInstance;*/
    }


public:

    Singleton() {}
    ~Singleton() {}


public:

    /*Singleton(const Singleton<T> &);
    Singleton& operator = (const Singleton<T> &);*/





    static Worker<T> worker;
};

template <typename T>
class Worker
{
    friend class Singleton<T>;
public:

    Worker()
    {
        i = 0;
        if ( !m_pInstance )
        {m_pInstance = new T();printf("ccc\n");}  // 出错行在这里
    }
    ~Worker()
    {if ( m_pInstance )
        {delete m_pInstance;printf("ddd\n");}  // 出错行在这里
    }
public:
    int i;
    T* m_pInstance;
};

//template <typename T> T* Singleton<T>::m_pInstance = NULL;
template <typename T> typename Worker<T> Singleton<T>::worker;

#define SINGLETON_INIT(Type) friend Type* Singleton<Type>::GetInstance(); private: Type(); ~Type()

#endif

或者是这样,都不行,编译结果一模一样:

 #ifndef __SINGLETON__H__
#define __SINGLETON__H__

template <typename T>
class Worker;

template <typename T>
class Singleton
{
    friend class Worker<T>;
public:

    static T* GetInstance()
    {
        worker.i=3;
        /*worker.m_pInstance = new T();
        return worker.m_pInstance;*/
    }


public:

    Singleton() {}
    ~Singleton() {}


public:

    /*Singleton(const Singleton<T> &);
    Singleton& operator = (const Singleton<T> &);*/


    static T* m_pInstance;


    static Worker<T> worker;
};

template <typename T>
class Worker
{
    friend class Singleton<T>;
public:

    Worker()
    {
        i = 0;
        if ( !Singleton<T>::m_pInstance )
        {Singleton<T>::m_pInstance = new T();printf("ccc\n");}  // 出错行在这里
    }
    ~Worker()
    {if ( Singleton<T>::m_pInstance )
        {delete Singleton<T>::m_pInstance;printf("ddd\n");}  // 出错行在这里
    }
public:
    int i;

};

template <typename T> T* Singleton<T>::m_pInstance = NULL;
template <typename T> typename Worker<T> Singleton<T>::worker;

#define SINGLETON_INIT(Type) friend Type* Singleton<Type>::GetInstance(); private: Type(); ~Type()

#endif

编译结果:
A::A”: 无法访问 private 成员(在“A”类中声明)

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

4条回答 默认 最新

  • qq_27183003 ysuwood 2015-11-29 23:04

    你的设计思路有问题,不知道要干什么用,设计得这么复杂,这么纠结。即使成功,效率也很低,又是模板类,又是继承。

    互为友元或者是内部类,然后调用对方的数据,这必然存在一个谁先定义的问题,A先定义,那么B还未定义,在A中就无法使用B。
    这个问题很难解决。

    点赞 1 评论 复制链接分享
  • qq_27183003 ysuwood 2015-11-29 13:42

    你怎么编译错误的?main()函数呢?

    点赞 评论 复制链接分享
  • lawala012 lawala012 2015-11-29 14:14

    另外两个文件:

    main.cpp:

     #include <stdio.h>
    #include "head.h"
    #include "Singleton.h"
    
    A::A()
    {
        //worker.i = 3;
        printf("zzz\n");
    }
    
    A::~A()
    {
        printf("mmm\n");
    }
    
    void main()
    {
        A* a = NULL;
        a = Singleton<A>::GetInstance();
        a->Aa();
    }
    

    head.h:

     #pragma once
    #include "Singleton.h"
    
    class A : public Singleton<A>
    {
    SINGLETON_INIT(A);
    public:
        void Aa(){printf("aaa\n");}
    };
    

    上面的文件改成内部类了,问题一样:

    Singleton.h:

     #ifndef __SINGLETON__H__
    #define __SINGLETON__H__
    
    template <typename T>
    class Singleton
    {
        friend class Worker;
    public:
    
        static T* GetInstance()
        {
            worker.i=3;
            /*worker.m_pInstance = new T();
            return worker.m_pInstance;*/
            return NULL;
        }
    
    
    public:
    
        Singleton() {}
        ~Singleton() {}
    
    
    public:
    
        /*Singleton(const Singleton<T> &);
        Singleton& operator = (const Singleton<T> &);*/
    
    
        class Worker
        {
            friend class Singleton<T>;
        public:
    
            Worker()
            {
                i = 0;
                if ( !m_pInstance )
                {m_pInstance = new T();printf("ccc\n");}  // 出错行在这里
            }
            ~Worker()
            {if ( m_pInstance )
            {delete m_pInstance;printf("ddd\n");}  // 出错行在这里
            }
        public:
            int i;
            T* m_pInstance;
        };
    
    
        static Worker worker;
    };
    
    //template <typename T> T* Singleton<T>::m_pInstance = NULL;
    template <typename T> typename Singleton<T>::Worker Singleton<T>::worker;
    
    #define SINGLETON_INIT(Type) friend Type* Singleton<Type>::GetInstance(); private: Type(); ~Type()
    
    #endif
    

    后来发现问题出在:
    #define SINGLETON_INIT(Type) friend Type* Singleton::GetInstance(); private: Type(); ~Type()
    这句的“private:”里,但我就想问,

    两个类都已经相互友元了啊!还没有权限访问私有成员?难道C++在类构造阶段友元是无效的???

    Worker类内,改成这样通过:

     Worker()
            {
            }
    
            void aaa()
            {
                i = 0;
                if ( !m_pInstance )
                {m_pInstance = new T();printf("ccc\n");} 
            }
    
            void bbb()
            {
                if ( m_pInstance )
                {delete m_pInstance;printf("ddd\n");} 
            }
            ~Worker()
            {
            }
    

    改成这样,牵涉到构造析构函数,又不行了:

     Worker()
            {
                aaa();
            }
    
            void aaa()
            {
                i = 0;
                if ( !m_pInstance )
                {m_pInstance = new T();printf("ccc\n");}
            }
    
            void bbb()
            {
                if ( m_pInstance )
                {delete m_pInstance;printf("ddd\n");} 
            }
            ~Worker()
            {bbb();
            }
    

    两个类都已经相互友元了啊!还没有权限访问私有成员?难道C++在类构造阶段友元是无效的???友元对构造析构函数不起作用?(重要问题说两遍)

    点赞 评论 复制链接分享
  • qq_27183003 ysuwood 2015-11-29 14:55

    互为友元类,可以有权限访问私有成员。但是要注意,私有成员是静态类型,可以直接访问。
    如果是非静态类型成员变量,要先用类定义对象,通过对象访问私有数据。否则没定义对象,该成员变量也不存在。

    点赞 评论 复制链接分享

相关推荐