用flask做网站郑州企业网站托管公司

当前位置: 首页 > news >正文

用flask做网站,郑州企业网站托管公司,域名查询ip地址138,延安网站建设公司电话CRTP#xff08;Curiously Recurring Template Pattern#xff0c;奇特重现模版模式#xff09;,是一种在C中使用模板来实现的设计模式#xff0c;主要用于实现编译时多态性#xff08;静态多态#xff09;。这种模式通过类模板和模板继承机制来实现#xff0c;使得派生…CRTPCuriously Recurring Template Pattern奇特重现模版模式,是一种在C中使用模板来实现的设计模式主要用于实现编译时多态性静态多态。这种模式通过类模板和模板继承机制来实现使得派生类在继承时将自身作为基类模板的参数。 这里采用的中文名字参考了zh.cppreference.com 示例解析 template typename T class Base { public:void doSomething(){// 访问 Derived 类的成员static_castT*(this)-implementation();} };class Derived : public BaseDerived { public:void implementation(){std::cout Derived::implementation();} };int main() {Derived d;d.doSomething();return 0; }输出结果 Derived::implementation()解析 编译器在编译上面代码时因为延迟实例化所以在Derived派生类后面实例化BaseDerived。在实例化的BaseDerived类的doSomething()函数中将this指针从BaseDerived*转换成Derived*这样就能访问Derived类中定义的方法了。 CRTP的多态性 C多态的实现方式分为动态多态虚函数、静态多态模板、函数重载。其中用模板实现静态多态的方式也有很多种 函数模板类模板CRTP通过模板继承实现 动态多态和静态多态 动态多态 动态多态是通过虚函数来实现的。它允许在运行时确定调用哪个对象/方法这主要依赖于虚函数表vtable来动态解析调用。
优点 灵活性可以在运行时改变对象的行为易于使用只需声明虚函数让派生类重写函数即可
缺点 性能开销每次调用虚函数时都需要通过虚指针转到虚函数表再找到对应的函数花费时间长内存开销每个对象都需要额外的内存来存储指向虚函数表的指针。 静态多态 静态多态通常是通过模板实现的它在编译时就明确了调用的对象/方法而不是在运行时。
优点 性能开销没有运行时的多余开销函数调用可以直接解析内存开销运行时不会有多余的内存开销
缺点 代码膨胀对于每个不同的类型编译器可能都会生成一份代码这可能导致最终编译出的二进制文件体积增大灵活性较低在编译时就已经确定了所有的类型不能像动态多态那样在运行时改变对象的行为 CRTP和虚函数 性能与开销 CRTP使用 CRTP 实现的是静态多态即在编译时就解析函数调用而不需要虚函数表从而避免了运行时的查找开销。这种方法通过模板实例化直接绑定函数因此运行效率更高没有额外的内存开销。虚函数动态多态通过虚函数实现。虚函数依赖于虚函数表vtable这意味着每次调用虚函数时都需要通过虚函数表进行间接跳转。这种间接性带来运行时开销同时每个使用虚函数的对象需要额外的内存来存储指向虚函数表的指针。
灵活性和可维护性 CRTPCRTP 允许基类通过模板机制访问派生类的成员这样可以将一些通用的功能封装在基类中而具体的实现则在派生类中完成。CRTP 特别适合于实现混入Mixins类型的功能能够在不修改原有类结构的情况下为类增加额外的功能。虚函数虚函数提供了极高的灵活性允许在运行时决定对象的行为。这使得代码可以容易地扩展和修改但可能导致代码维护和理解的复杂度增加。
代码重用与扩展 CRTPCRTP 允许基类通过模板机制访问派生类的成员这样可以将一些通用的功能封装在基类中而具体的实现则在派生类中完成。CRTP 特别适合于实现混入Mixins类型的功能能够在不修改原有类结构的情况下为类增加额外的功能。 上面提到的混入Mixins指的是在面向对象编程中用于增加类功能的技术它通过多重继承将功能模块Mixin类混入到一个类中。这种方法允许程序员在不修改原始类代码的情况下为类添加新的行为和属性。 虚函数通过虚函数派生类可以覆盖基类中的行为实现功能的自定义和扩展。这种方法简洁直观易于理解和使用。
类型安全和错误检测 CRTP由于 CRTP 是在编译时处理的所以相关的类型错误会在编译阶段被捕捉和报告增加了开发过程中的类型安全性。虚函数虚函数的错误如类型不匹配通常在运行时发现有时这可能导致程序崩溃或不稳定。
CRTP的案例展示 enable_shared_from_this enable_shared_from_this就是一个典型的CRTP案例继承enable_shared_from_this类的对象可以从内部生成std::shared_ptr。 这个模板类最初是Boost库引入的后面被纳入到C标准库中下面我们展示Boost库下的源码 namespace boost {templateclass T class enable_shared_from_this { protected:BOOST_CONSTEXPR enable_shared_from_this() BOOST_SP_NOEXCEPT{}BOOST_CONSTEXPR enable_shared_from_this(enable_shared_from_this const ) BOOST_SP_NOEXCEPT{}enable_shared_from_this operator(enable_shared_from_this const ) BOOST_SP_NOEXCEPT{return *this;}~enable_shared_from_this() BOOST_SP_NOEXCEPT // ~weak_ptrT newer throws, so this call also must not throw{}public:shared_ptrT shared_from_this(){shared_ptrT p( weakthis );BOOST_ASSERT( p.get() this );return p;}shared_ptrT const shared_from_this() const{shared_ptrT const p( weakthis );BOOST_ASSERT( p.get() this );return p;}weak_ptrT weak_from_this() BOOST_SP_NOEXCEPT{return weakthis;}weak_ptrT const weak_from_this() const BOOST_SP_NOEXCEPT{return weakthis;}public: // actually private, but avoids compiler template friendship issues// Note: invoked automatically by shared_ptr; do not calltemplateclass X, class Y void _internal_accept_owner( shared_ptrX const * ppx, Y * py ) const BOOST_SP_NOEXCEPT{if( weakthis.expired() ){weakthis shared_ptrT( ppx, py );}}private:mutable weak_ptrT weakthis; };} // namespace boost下面展示使用标准库中的enable_shared_from_this示例 #include memory #include iostreamclass MyClass : public std::enable_shared_from_thisMyClass { public:std::shared_ptrMyClass get_shared_ptr() {return shared_from_this();} };int main() {std::shared_ptrMyClass ptr std::make_sharedMyClass();std::shared_ptrMyClass another_ptr ptr-get_shared_ptr();std::cout Same object: (ptr another_ptr) std::endl; }日志类 templatetypename T class Logging { public:void log(const std::string message) const {// 获取派生类的名称这里假设派生类有一个名为 getName 的方法std::cout static_castconst T(this)-getName() : message std::endl;} };class Car : public LoggingCar { public:Car(const std::string model) : model(model) {}std::string getName() const { return model; }void drive() {this-log(Starting the engine.);// 驾驶逻辑…this-log(Stopped the engine.);}private:std::string model; };class Robot : public LoggingRobot { public:Robot(const std::string identifier) : identifier(identifier) {}std::string getName() const { return identifier; }void operate() {this-log(Activating robot.);// 操作逻辑…this-log(Deactivating robot.);}private:std::string identifier; };int main() {Car car(Toyota Camry);car.drive();Robot robot(Android 007);robot.operate();return 0; }总结 我总结了CRTP的具体应用场景 使用虚函数有性能问题需要优化可以将虚函数转成CRTP后续文章会介绍能够抽象出通用方法派生类只使用方法不重写/修改方法需要基于现有的通用方法来添加新功能不改变通用方法 其实在使用CRTP和虚函数的核心区别是CRTP的继承关系中能够抽象出通用方法且不会修改通用方法而虚函数是抽象出通用方法但要重写方法只是把通用方法当做一个入口。