类模板的三种表达方式

简介: 类模板的三种表达方式

一:所有的类模板函数写在类的内部

template <typename T>
class A {
public:
  A(T a=0) {
    this->a = a;
  }
  T& getA() {
    return this->a;
  }
  A operator+(const A& other) {
    A temp;//要求A的构造函数要有默认值
    temp.a = this->a + other.a;
    return temp;
  }
private:
  T a;
};

二:所有的类模板函数写在类的外部,同一个.cpp文件中

template <typename T>
class A {
public:
  A(T a = 0);
  T& getA();
  A operator+(const A& other);
private:
  T a;
};
template <typename T>
A<T>::A(T a ) {
  this->a = a;
}
template <typename T>
T& A<T>::getA() {
  return this->a;
}
template <typename T>
A<T> A<T>::operator+(const A<T>& other) {
  A temp;//类的内部可以显示声明也可以不显示
  temp.a = this->a + other.a;
  return temp;
}

注意:

三:所有的类模板函数写在类的外部,在不同的.h和.cpp文件中

方式一:main函数处在A.cpp文件中

A.h

#pragma once
template <typename T>
class A {
public:
  A(T a = 0);
  T& getA();
  A operator+(const A& other);
private:
  T a;
};

A.cpp

#include "A.h"
template <typename T>
A<T>::A(T a) {
  this->a = a;
}
template <typename T>
T& A<T>::getA() {
  return this->a;
}
template <typename T>
A<T> A<T>::operator+(const A<T>& other) {
  A temp;//类的内部可以显示声明也可以不显示
  temp.a = this->a + other.a;
  return temp;
}
int main(void) {
  A<int> a(100);
  A<int> b(200);
  cout << a.getA() << endl;
  cout << b.getA() << endl;
  A<int> temp = a + b;
  cout << temp.getA() << endl;
  return 0;
}

方式二: main函数不在A.cpp文件中

A.h

#pragma once
#include<iostream>
using namespace std;
template <typename T>
class A {
public:
  A(T a = 0);
  T& getA();
  A operator+(const A& other);
private:
  T a;
};

A.cpp

#include "A.h"
template <typename T>
A<T>::A(T a) {
  this->a = a;
}
template <typename T>
T& A<T>::getA() {
  return this->a;
}
template <typename T>
A<T> A<T>::operator+(const A<T>& other) {
  A temp;//类的内部可以显示声明也可以不显示
  temp.a = this->a + other.a;
  return temp;
}

main.cpp   特别注意:此时不可包含模板类的头文件,需要包含模板类的.cpp函数实现文件,否则编译器报错

#include<iostream>
#include"A.cpp"
using namespace std;
int main(void) {
  A<int> a(100);
  A<int> b(200);
  cout << a.getA() << endl;
  cout << b.getA() << endl;
  A<int> temp = a + b;
  cout << temp.getA() << endl;
  return 0;
}

提示:根据业内不成文的规定,模板类的具体实现文件一般命名为.hpp,此时主函数文件中需要同时包含此.hpp文件,这种命名方式可读性更好.

四:特殊情况,友元函数

#include<iostream>
using namespace std;
template <typename T>
class A {
public:
  A(T a = 0);
  T& getA();
  A operator+(const A& other);
  template <typename T> //必须写成该模式
  friend A<T> addA(const A<T>& a, const A<T>& b);
private:
  T a;
};
template <typename T>
A<T> addA(const A<T>& a, const A<T>& b) {
  A<T>temp;//友元函数不属于类的内部,所以必须声明
  temp.a = a.a + b.a;
  return temp;
}
template <typename T>
A<T>::A(T a ) {
  this->a = a;
}
template <typename T>
T& A<T>::getA() {
  return this->a;
}
template <typename T>
A<T> A<T>::operator+(const A<T>& other) {
  A temp;//类的内部可以显示声明也可以不显示
  temp.a = this->a + other.a;
  return temp;
}
int main(void) {
  A<int> a(100);
  A<int> b(200);
  A<int> temp = addA<int>(a, b);//300
  cout << temp.getA() << endl;
  return 0;
}

友元函数在模板类中的使用总结:

(1)类的内部声明必须写成如下例子的形式:

template <typename T>
friend A<T> addA(const A<T>& a, const A<T>& b);

(2)友元函数的实现必须写成:

template <typename T>
A<T> addA(const A<T>& a, const A<T>& b) {
  A<T>temp;//友元函数不属于类的内部,所以必须声明
  temp.a = a.a + b.a;
  return temp;
}

(3)友元函数的调用必须写成:

A<int> a(100);
A<int> b(200);
A<int> temp = addA<int>(a, b);//300

 

 

 

目录
相关文章
|
10月前
|
C++
60 C++ - 类模板的应用
60 C++ - 类模板的应用
26 0
|
10月前
|
编译器 Linux C++
59 C++ - 类模板
59 C++ - 类模板
48 0
|
2月前
|
算法 编译器 程序员
|
4月前
|
编译器 C++
39类模板
39类模板
18 0
|
10月前
|
算法 编译器 C++
C++泛型编程之类模板
C++泛型编程之类模板
42 0
|
编译器 C++
类模板总结
所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。
|
编译器 C++
C++函数模板与类模板
C++函数模板与类模板
73 0
|
编译器 C++
【C++】什么是函数模板/类模板?
1.什么是函数模板? 函数模板简单来说就是一个模板,与函数参数的类型无关,是一个模子,不是真正的函数,实例化的函数会根据实参的类型自动推导类型。
|
存储 编译器 C++
【C++要笑着学】泛型编程 | 函数模板 | 函数模板实例化 | 类模板(二)
本章将正式开始介绍C++中的模板,为了能让大家更好地体会到用模板多是件美事!我们将会举例说明,大家可以试着把自己带入到文章中,跟着思路去阅读和思考,真的会很有意思!如果你对网络流行梗有了解,读起来将会更有意思!
130 1
【C++要笑着学】泛型编程 | 函数模板 | 函数模板实例化 | 类模板(二)
|
算法 编译器 C++
C++模板(类模板)
C++模板(类模板)
103 0