当前位置: 移动技术网 > 移动技术>移动开发>IOS > C++模板-36-类模板和继承和友元

C++模板-36-类模板和继承和友元

2020年07月17日  | 移动技术网移动技术  | 我要评论

这里来学习下类模板作为父类,那么子类继承父类是有问题,这种问题是什么,如何解决。然后看看类模板配合友元函数的类内实现和类外实现。

 

1.类模板和继承

如果父类是一个模板类,子类继承的时候会有下面几个点需要注意

  1. 当子类继承的父类是一个类模板时,子类在声明的时候,要指定出父类中T的类型
  2. 如果不指定,编译器无法给与子类分配内存
  3. 如果想灵活指定出父类中T的类型,子类也需要为类模板

先用代码演示1,2点,如果不指定父类T的类型,这个编译错误是什么

#include <iostream>
#include <string>
using namespace std;

//类模板
template <class T>
class Base
{
    T m;
};

// 子类
class Sun : public Base
{


};


void test01()
{
    
}

int main()
{
    test01();
    system("pause");
    return 0;
}

上面代码在13行 Base这里会报错,内容是“缺少 类模板 "Base" 的参数列表”,所以这里不能直接继承。因为编译器无法分配内存,我们知道一个空的类对象是4字节的大小内存,但是子类不知道父类T的类型,所以成员变量没法知道大小,从而无法分配内存。例如父类T m 由于数据类型不同,内存大小是不同的。

 

2. 把子类也写成模板,灵活继承父类

如果要灵活使用父类这种模板类,子类也需要改成模板类。

#include <iostream>
#include <string>
using namespace std;

//类模板
template <class T>
class Base
{
    T m;
};

// 子类
template <class T1, class T2>
class Sun : public Base<T2>
{
    

};


void test01()
{
    
}

int main()
{
    test01();
    system("pause");
    return 0;
}

还是在13 14行,T1表示子类中继承下来的m的类型, T2表示父类中m的类型。

 

3.友元函数配合模板类内实现

先复习下什么是友元,就是使用关键字friend,告诉编译器,可以访问这个类下的私有成员变量和函数。例如下面定义这个全局函数就是friend修饰,就可以通过传入对象p进行访问到Person类的私有成员m_Name和m_Age。

#include <iostream>
#include <string>
using namespace std;

//类模板
template <class T1, class T2>
class Person
{
    // 全局函数
    friend void printPerson(Person<T1, T2> p)
    {
        cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Age << endl;

    }

public:
    Person(T1 name,T2 age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }

private:
    T1 m_Name;
    T2 m_Age;
};


void test01()
{
    Person<string, int>p("Anthony", 18);
    printPerson(p);
}

int main()
{
    test01();
    system("pause");
    return 0;
}

友元在模板类中实现很简单,直接在类内就实现。接下来如何看使用友元,但是模板类的成员函数是在类外实现。

#include <iostream>
#include <string>
using namespace std;

// 类外实现
template <class T1, class T2>
class Person;

// 告诉编译器这是一个模板函数
template <class T1, class T2>
void printPerson(Person<T1, T2> p)
{
    cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Age << endl;
}

//类模板
template <class T1, class T2>
class Person
{
    // 全局函数类外实现
    friend void printPerson<>(Person<T1, T2> p);
   
public:
    Person(T1 name,T2 age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }

private:
    T1 m_Name;
    T2 m_Age;
};

void test01()
{
    Person<string, int>p("Anthony", 18);
    printPerson(p);
}

int main()
{
    test01();
    system("pause");
    return 0;
}

全局函数类外实现比较复杂,第一 类模板声明放前面,告诉编译器Person是模板类,第二 全局函数实现也放前面,也是让编译器提前知道有这个全局函数,第三 类内部全局函数声明,其中加<>表示这个全局函数已经不是一个普通函数,而是变成一个模板函数。

 

 

本文地址:https://blog.csdn.net/u011541946/article/details/107349604

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网