类模板是创建类的模式

12 篇文章 0 订阅
本文详细介绍了C++中的类模板和函数模板,包括如何通过模板参数创建不同类型的类实例,以及类模板内的成员函数模板、类型转换、重载操作符等概念。
摘要由CSDN通过智能技术生成
  1. 类模板和函数模板一样,使用关键字template引入一个类模板。类模板是创建类的模式,通过提供模板参数来实现,例如Point<int>

  2. 类模板的成员函数本身就是函数模板,使用相同的模板参数,只是将模板参数提供给类,而不是函数,就像在下面示例中函数Point<T>::moveTo实现的那样。

  3. 每当使用不同的模板参数时,编译器就会生成一个新的类实例,具有新的成员函数。
    也就是说,Point<int>::moveTo是一个函数,Point<double>::moveTo是另一个函数,这正是手动编写这些函数会发生的情况。如果两个不同的源文件都使用Point<int>,编译器和链接器会确保它们共享同一个模板实例。

  4. 也正因为如此不能把一个Point<int>对象赋给一个Point<float>对象,详见下面代码中注释掉的pt3 = pt2后面的报错信息。

  5. 下面代码也给出了类内又有模板的实现方式。

#include <iostream>
#include <vector>

template<class T>
class Point{
public:
    Point(T x, T y):x_(x), y_(y){
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }

    Point(const Point& pt): x_(pt.x_), y_(pt.y_){
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
    Point& operator=(const Point& pt)& {
        Point(pt.x_, pt.y_).swap(static_cast<Point&>(*this));
        std::cout << __PRETTY_FUNCTION__ << std::endl;

        return *this;
    }

    Point(Point&& pt) noexcept: x_(pt.x_), y_(pt.y_) {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
    Point& operator=(Point&& pt)& noexcept{
        x_ = pt.x_;
        y_ = pt.y_;
        std::cout << __PRETTY_FUNCTION__ << std::endl;

        return *this;
    }

    void swap(Point& pt) noexcept{
        std::swap(x_, pt.x_);
        std::swap(y_, pt.y_);
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }

    virtual ~Point(){
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }

    T getX()const{
        return x_;
    }
    T getY()const{
        return y_;
    }

    void moveTo(T x, T y);

    /*【类内又有模板】方式一,在类内声明,在类外定义,类外定义时需要注意模板头template header的堆叠方式,上面是类模板头、下面是函数模板头 */
    template<class U>
    U ratio() ;

    /*【类内又有模板】方式二,在类内定义 */
    template<class V>
    V multiply() {
        return static_cast<V>(x_) * static_cast<V>(y_);
    }

private:
    T x_;
    T y_;
};

template<class T>
void Point<T>::moveTo(T x, T y){
    x_ = x;
    y_ = y;
}

template<class T>
template<class U>
U Point<T>::ratio() {
    return static_cast<U>(x_) / static_cast<U>(y_); // omit devided by zero.
}

int main() {
    Point<int> pt1(1, 2);
    Point<float> pt2(3.4, 5.6);

    Point<int> pt3(pt1);
    pt3 = pt1;
    //pt3 = pt2;  // error: no match for 'operator=' (operand types are 'Point<int>' and 'Point<float>')

    std::cout << "x = "<< pt3.getX() << ", y = " << pt3.getY() << std::endl;  // x = 1, y = 2】

    pt3.moveTo(5, 6);

    std::cout << "x = "<< pt3.getX() << ", y = " << pt3.getY() << std::endl;  // x = 5, y = 6

    std::cout << pt3.ratio<float>() << std::endl;     // 0.833333
    std::cout << pt3.multiply<float>() << std::endl;  // 30
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值