zoukankan      html  css  js  c++  java
  • 模板类中使用友元函数的方式,派生类友元函数对基类的成员使用情况

    在一般友元函数的前面加上 template<typename T),注意在函数的声明和定义处都要加这个模板

    例如:

    //模板类,长方体类
    template <typename ElementType>
    class Rectangle
    {
        ///*重载基类的输入输出运算符*/
        //template<typename ElementType>
        //friend std::istream& operator >> (std::istream& in, Rectangle<ElementType>& item);
        //template<typename ElementType>
        //friend std::ostream& operator << (std::ostream& out, const Rectangle<ElementType>& item);
    
    protected:        //受保护的成员
        ElementType length;        //长方体的长,在类内部可以直接使用模板定义的数据类型
        ElementType width;        //长方体的宽
        RectangleNo myNo;        //长方形的序号,嵌套类对象作为Rectangle类的一个数据成员
    
    };

    友元函数的定义部分也要加上template<typename T>这个模板

    /*重载输入运算符*/
    template <typename ElementType>
    std::istream& operator >> (std::istream& in, Rectangle<ElementType>& item)
    {
        in >> item.length >> item.width >> item.myNo.no;
        return in;
    }
    
    /*重载输出运算符*/
    template<typename ElementType>
    std::ostream& operator << (std::ostream& out, const Rectangle<ElementType>& item)
    {
        out << "length = " << item.length << " width = " << item.width << "    No = " << item.myNo.no;
        return out;
    }

    如果不知道怎么声明模板类的友元函数,可以在类内部用函数实现你想用友元函数实现的功能,

    然后在类外的友元函数中调用这个类内函数,就可以达到相同的效果

    例如:上面那个输入输出的友元函数可以改成:

    //模板类,长方体类
    template <typename ElementType>
    class Rectangle
    {
    public:
        //读取长方形
        void read(std::istream& in);
        
        //输出长方形
        void display(std::ostream& out)const ;
    protected:        //受保护的成员
        ElementType length;        //长方体的长,在类内部可以直接使用模板定义的数据类型
        ElementType width;        //长方体的宽
        RectangleNo myNo;        //长方形的序号,嵌套类对象作为Rectangle类的一个数据成员
    };

    在类外实现read和display函数后,在类外的友元函数中调用这两个函数即可

    template<typename ElementType>
    void MyRectangle<ElementType>::read(std::istream& in)
    {
        cout << "Please enter the length and width of " << myNo.no << endl;
        in >> length >> width;
    }
    
    template<typename ElementType>
    void MyRectangle<ElementType>::display(std::ostream& out) const
    {
        out << "the " << myNo.no << " Rectangle's length =   " << length << " width = " << width;
    }
    
    template<typename ElementType>
    std::ostream& operator << (std::ostream& out, const Rectangle<ElementType>& item)
    {
        item.display(out);
        return out;
    }
    
    template<typename ElementType>
    std::istream& operator >> (std::istream& in, Rectangle<ElementType>& item)
    {
        item.read(in);
        return in;
    }

    派生类友元函数对基类的成员使用情况:

    派生类友元函数可以使用基类中非private成员,可以使用基类的protected和public成员

    基类的成员函数(包括友元函数)只能操作派生类对象中基类那部分。

    如果派生类中有函数和基类同名,那么派生类对象会调用派生类中的那个函数,而不是对象的基类部分调用基类函数,派生类部分调用派生类函数。

  • 相关阅读:
    Hibernate映射之数组属性, 集合属性(list、set和map)
    org.hibernate.type.SerializationException: could not deserialize 反序列化失败
    linux下同一个tomcat部署多个项目
    Nexus私服 Maven
    maven 父子项目 聚合与继承 生命周期 打包插件 依赖打包 jar pom war
    IDEA中创建Web聚合项目(Maven多模块项目)
    为什么要在linux命令前加上 ./ 什么时候才需要在命令前加上./
    web.xml 介绍 and pom.xml 介绍
    有趣的linux命令
    SpringMVC 中常见注释
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/9809591.html
Copyright © 2011-2022 走看看