C++ CRTP 超级简介

318 阅读1分钟
引子

先来一个动物园的例子。 比如:一个类 Animal 基类 还有 cat/dog。。。等等。

class Zoo {
 private:
    std::vector<shared_ptr<Animal>> animals;
 public:
    void lunch() {
        for (auto animal : animals) {
            animal->eat();
        }
    }
} ;

这是一个传统的oo写法。 而模版有另一个写法,模板的方法也比oo要好。不需要获取虚函数表,再运行。而是在编译期就把函数放在正确的位置上。

通过模板实现静态绑定
#include <iostream>

template<typename T>
class Base {
 public:
    void show () const {
        static_cast<const T*>(this)->show();
    }
};

class Derived: public Base<Derived> {
 public:
    void show () const {
        std::cout << "Shown in Derived class." << std::endl;
    }
};

int main () {
    Derived d;
    Base<Derived> *b = &d;
    b->show();
    return 0;
}

但是,这样不具备多态性,无法将所有Animal放到一个容器里。 解决方法: 只要将BaseTmp 继承自Base 即可

class Base{
	public:
		virtual void eat()=0;
};

template<typename T>
class BaseTmp:public Base{
	public:
		void eat(){
			static_cast<T*>(this)->eat();
		}
};

class Devic:public BaseTmp<Devic>{
	public:
		void eat(){
			cout << "Dec eat" << endl;
		}
};


int main(){
	Devic d;
	Base *b = &d;
	b->eat();
	return 0;
}