美文网首页C++ 2a
C++中的友元模版

C++中的友元模版

作者: 左图右码 | 来源:发表于2022-05-21 19:06 被阅读0次

友元在C++中意味着不好的设计,因忽略访问属性的限制,破坏了封装性。我却很喜欢这个特性。
特别说明,这个特性适合库作者,一般的使用者可能意义不大,尤其是作为代码的搬运工。
在非模版的设计中,有些时候,在写目标类的时候尚不能确定那个类成为友元类,只能后期增加友元类的声明,这就导致目标类的代码不能封闭。模版可以解决这个问题,将友元类的设置延后到编译阶段。
比如有个日志类,有私有的方法和私有数据成员。想要直接访问私有数据成员,除了用公开的get/set外,就只能用友元了。通过模版,这个myLog类的代码就能封闭了。

template<typename T> 
class myLog
{
    friend T;
    std::string str;
    void print()
    {
        std::cout << str << std::endl;
    }
public:
    myLog() = default;
};
class writeDataToLog
{
private:
    using Log = myLog<writeDataToLog>;
    Log _log;
public:
    void setval(std::string data) {
        _log.str = data;
    }
    void print()
    {
        _log.print();
    }
};

重要的就是friend T;这一句,在writeDataToLog里就可以直接变身为myLog的友元,调用私有的变量和函数。
如果T是普通类型如int,double等,这一句是被编译器忽略的,不会有副作用。所以如果定义一个别名来直接使用类型无关的myLog:

using myLog_t = myLog<void>;
myLog_t log;

如果还不能说明友元模版的必要性,我们看看另外一个例子(重点在第14行),这是个使用引用计数的智能指针的片段:

template<typename T>
class SmartPointer
{
   T* pointer = nullptr;
   ReferenceCount* refcount = nullptr;
  //友元模板,让其它类型的智能指针可以直接访问私有变量
  template<typename>
  friend class SmartPointer;
  //...     
  //有继承关系的构造,向上转换,U继承自T
  template<typename U, typename = std::enable_if_t<std::is_base_of_v<T, U>>>
  SmartPointer(SmartPointer<U> const& other)
  {
    if (pointer = other.pointer, refcount = other.refcount)  //友元模板的设置才能访问other的私有变量
    {
        refcount->increment();
    }
  }
  //...
}

如果像让不同的每个myLog的实例类都能互相访问私有数据,则可以这么做:

template<typename T> 
class myLog
{
    //...
    template<typename>
    friend class myLog;
    //...
}

这样,myLog家族类之间就没有秘密了。仔细琢磨,这挺神奇的。

相关文章

  • C++中的友元模版

    友元在C++中意味着不好的设计,因忽略访问属性的限制,破坏了封装性。我却很喜欢这个特性。特别说明,这个特性适合库作...

  • c++ 友元

    在c++中,通过关键字friend声明为友元。友元可以范围与其有好友关系的类中私有成员。友元包括友元函数和友元类。...

  • C++中的友元

    友元的介绍 什么是友元?友元是C++中的一种关系友元关系发生在函数与类之间或者类与类之间友元关系是单项的,不能传递...

  • 读书笔记17.06.03

    C++ STL:Listlist是C++标准模版库(STL,Standard Template Library)中...

  • 7. C++友元函数和友元类

    7.1 友元函数 C++只有本类中的函数可以访问本类的 private 成员。 但一种情况例外,那就是友元(fri...

  • 2001.C++BASE-friend(友元)

    转:关于C++中的友元函数的总结 1.友元函数的简单介绍 1.1为什么要使用友元函数 在实现类之间数据共享时,减少...

  • C++语言基础(03)

    1.内存分配 C/C++ 内存分区: java 创建对象 2.常函数 3.友元函数和友元类 友元函数 友元类 4....

  • c++语法2

    接上篇我们继续学习静态成员、友元函数、继承、多重继承,继承访问权限等 静态成员与友元函数:c++中静态成员与jav...

  • C++友元

    friend类: 如果class A想让class B访问它的成员,只需要在class A中将class B声明称...

  • C++友元

    我承认你是我的朋友,你才是,当有一天,我觉得你有背叛我,除了你的名,你就再也不会进入我的内心。

网友评论

    本文标题:C++中的友元模版

    本文链接:https://www.haomeiwen.com/subject/sdocprtx.html