在实际示例中如何从CRTP中受益?

时间:2018-12-17 21:48:15

标签: c++ crtp

根据我的理解,当类是从模板化基类的特殊化派生的时,将使用CRTP(奇怪地重复使用模板模式)。因此,基类可以访问派生类的功能,然后在将Parameter强制转换为派生类后委托给派生类。这是一个示例:

#include <iostream>
using namespace std;


template< class T> 
class Shape2D{
    public:
        Shape2D(double, double);
        virtual ~Shape2D();

        void SetDims(double dim1, double dim2) {
            static_cast<T*>(this)->SetDims(dim1, dim2);
        }

        double GetDim1() const;
        double GetDim2() const;
        double GetSurface()const;
        double GetPerim()const;
};

template<class T>
Shape2D<T>::Shape2D(double dim1, double dim2) {
    static_cast<T*>(this)->SetDims(dim1, dim2);
}

template<class T>
Shape2D<T>::~Shape2D() {

}


template<class T>
double Shape2D<T>::GetSurface()const {
    return static_cast<const T*>(this)->GetSurface();
}

template<class T>
double Shape2D<T>::GetDim1()const {
    return static_cast<const T*>(this)->GetDim1();
}

template<class T>
double Shape2D<T>::GetDim2()const {
    return static_cast<const T*>(this)->GetDim2();
}

template<class T>
double Shape2D<T>::GetPerim()const {
    return static_cast<const T*>(this)->GetPerim();
}

class Rectangle : public Shape2D<class Rectangle> {
    public:
        Rectangle(double, double);

        void SetDims(double, double);

        double GetDim1() const;
        double GetDim2() const;
        double GetSurface()const;
        double GetPerim()const;

        private:
            double itsLength, itsWidth;
};

Rectangle::Rectangle(double len, double wid) :
    itsLength(len), itsWidth(wid), Shape2D<Rectangle>(len, wid) {

}

void Rectangle::SetDims(double len, double wid) {
    itsLength = len;
    itsWidth = wid;
}

double Rectangle::GetDim1()const{
    return itsLength;
}

double Rectangle::GetDim2()const {
    return itsWidth;
}

double Rectangle::GetSurface()const {
    return itsLength * itsWidth;
}

double Rectangle::GetPerim()const {
    return ((itsLength * 2) + (itsWidth * 2));
}

int main() {

    class Rectangle rct(7, 5);
    cout << rct.GetSurface() << endl;
    cout << rct.GetPerim() << endl;

    cout << endl;

    Shape2D<class Rectangle>* pSh2DRect = 
        new Shape2D<class Rectangle>(7, 5);
    cout << "Surface: " << pSh2DRect->GetSurface() << endl;
    cout << "Perimeter: " << pSh2DRect->GetPerim() << endl;

    delete pSh2DRect;


    cout << endl;
    std::cin.get();
}
  • 我看不到上述任何好处,因为没有CRTP就可以实现。
  • 我想要一个有用的示例,以消除我对静态多态性的怀疑。
  • 如果派生的class 不继承自派生类不是模板基类参数的专业化,该怎么办?例如:

    class Parallelogram : public Shape2D<Rectangle>{
         public:
            //...
    };
    

如您所见,Parallelogram通常继承自Shape2D<Parallelogram>而不是Rectangle。这是未定义的行为吗?

0 个答案:

没有答案