模板类构造函数与析构函数无法访问私有成员(明明就是公有的)
写成这样:
#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”类中声明)
你怎么编译错误的?main()函数呢?
另外两个文件:
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++在类构造阶段友元是无效的???友元对构造析构函数不起作用?(重要问题说两遍)
互为友元类,可以有权限访问私有成员。但是要注意,私有成员是静态类型,可以直接访问。
如果是非静态类型成员变量,要先用类定义对象,通过对象访问私有数据。否则没定义对象,该成员变量也不存在。
你的设计思路有问题,不知道要干什么用,设计得这么复杂,这么纠结。即使成功,效率也很低,又是模板类,又是继承。
互为友元或者是内部类,然后调用对方的数据,这必然存在一个谁先定义的问题,A先定义,那么B还未定义,在A中就无法使用B。
这个问题很难解决。