当前位置: 代码迷 >> 综合 >> C++模板-36-类模板和继承和友元
  详细解决方案

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

热度:20   发布时间:2024-01-28 09:20:04.0

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

 

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是模板类,第二 全局函数实现也放前面,也是让编译器提前知道有这个全局函数,第三 类内部全局函数声明,其中加<>表示这个全局函数已经不是一个普通函数,而是变成一个模板函数。

 

 

  相关解决方案