namespace MyNm
{
class MyClass {};
void dosomething(MyClass* my) { std::cout << typeid(*my).name() << std::endl; }
}
MyNm::MyClass mlc;
class PointS
{
public:
int _value;
public:
PointS(int data,const std::string& name):_data(data),_name(name){}
private:
int _data;
std::string _name;
};
template<int PointS::*Member>
class Access
{
public:
friend int GetPrivateData(PointS& obj)
{
return obj.*Member;
}
};
template class Access<&PointS::_data>;
//no friend key
template<typename Tag>
class DAccess
{
public:
inline static typename Tag::type ptr;
};
template<typename Tag,typename Tag::type V>
struct PtrTaker
{
struct Transferer {
Transferer() {
DAccess<Tag>::ptr = V;
}
};
inline static Transferer tr;
};
struct TagInt
{
using type = int PointS::*;
};
struct TagString
{
using type = std::string PointS::*;
};
template class PtrTaker<TagInt, &PointS::_data>;
template class PtrTaker<TagString, &PointS::_name>;
int main(int argc, char** argv)
{
//不声明获取类私有变量
PointS obj(100,"hello");
obj._value = 50;
//外部类声明friend
std::cout << GetPrivateData(obj) << std::endl;
//基于模板 不需要friend方式
std::cout << obj.*DAccess<TagInt>::ptr << std::endl;
std::cout << obj.*DAccess<TagString>::ptr << std::endl;
//下面是上述模板原理,成员指针
int PointS::*ptr = &PointS::_value;
obj.*ptr = 10;
//ADL 创建myclass后 dosomething可以不用显示声明命名空间
MyNm::MyClass myc;
//do not need call namespace
dosomething(&myc);
return 0;
}