软件框架-无绪开发2

    xiaoxiao2021-03-25  207

    1. 工厂方法优于构造函数<使用工厂方法代替构造函数>

    优点:  (1)工厂方法返回值并不一定是声明类型的实例,可以是它的子类实例 代码更加简洁。 ------(更好体现多态) (2)每次返回的对象也并不一定都是新创建的对象,完全可以将其缓存。相比每次调用构造函数都创建一个实例,而工厂方法可以缓存以前创建的对象,并重用它们,节省内存。 (3)对同步的控制,在工厂方法中可以将创建对象前后的相应代码进行统一处理;构造函数对于这种情况就无能为力了 (4)工厂方法支持参数化的返回类型,但构造函数是做不到这一点的 (5)工厂方法是一个方法,一个方法并不会限定返回值实例的类型,可以是类,也可以是接口;但构造函数的返回值却一定是指定的实例。

    2.让所有内容都不可更改

    设计的类如果不考虑让其拥有子类,就应该让这个类不能被继承 (1)private修饰 (2)转换,使用工厂方法 (3)final修饰,强制外部无法继承此类 #include <iostream> using namespace std; template <typename T> class Base{ friend T; private: Base(){ cout << "base" << endl; } ~Base(){} }; class B:virtual public Base<B>{ //一定注意 必须是虚继承 public: B(){ cout << "B" << endl; } }; class C:public B{ public: C(){} //继承时报错,无法通过编译 }; int main(){ B b; //B类无法被继承 //C c; return 0; }类Base的构造函数和析构函数因为是私有的,只有Base类的友元可以访问,B类在继承时将模板的参数设置为了B类,所以构造B类对象时们可以直接访问父类(Base)的构造函数。 为什么必须是虚继承(virtual)呢? 参见 c++Primer 4th 第17.3.7节 特殊的初始化语义 通常每个类只初始化自己的直接基类,但是在虚继承的时候这个情况发生了变化,可能导致虚基类被多次初始化,这显然不是我们想要的。(例2: AA,AB都是类A的派生类,然后类C又继承自AA和AB,如果按之前的方法会导致C里面A被初始化两次,也会存在两份数据) 为了解决重复初始化的问题,从具有虚基类的类继承的类在初始化时进行了特殊处理,在虚派生中,由最低层次的派生类的构造函数初始化虚基类。在我们上面的例1中就是由C的构造函数控制如何进行虚基类的初始化。 为什么B类不能被继承? 回到例1,因为B是Base的友元,所以B对象可以正常创建,但由于B使用了虚继承,所以如果要创建C对象,那么C类的构造函数就要负责虚基类(Base)的构造,但是Base的构造函数是私有的,C没有访问的权限(ps:友元关系不能被继承的),所以例1中的C类在编译时就会报错。这样B类就不能被继承了。

    C++11 

    #include "stdafx.h"   #include <iostream>      // 标示符含义:   // override,表示此虚函数必定“重写”了基类中的对应虚函数。   // final,(1)作用在虚函数:表示此虚函数已处在“最终”状态,后代类必定不能重写这个虚函数。   //        (2)作用在类:表示此类必定不能被继承   // 编译器将帮你检查是否“必定”      class B1 final {}; // 此类不能被继承   // class D1: public B1 {}; // error!      class B   {   public:   //  virtual void func() override // error! 指定了重写但实际并没重写,没有基类   //  {    //      std::cout << __FUNCTION__ << std::endl;   //  }       virtual void f() const        {            std::cout << __FUNCTION__ << std::endl;       }       virtual void fun()        {            std::cout << __FUNCTION__ << std::endl;        }   };      class D : public B   {   public:       virtual void f(int)      // ok! 隐藏,由于没有重写同名函数B::f,在D中变为不可见       {            std::cout << "hiding: " <<__FUNCTION__ << std::endl;        }    //  virtual void f() override   // error! 指定了重写但实际并没重写,类型声明不完全相同   //  {    //      std::cout << __FUNCTION__ << std::endl;    //  }        virtual void fun() override final // ok! 指定了重写实际上也重写了,同时,指定为最终,后代类中不能再重写此虚函数       {            std::cout << __FUNCTION__ << std::endl;        }    };      class D2 : public D   {   public:       virtual void f() const      // ok! 重写B::f(),同时,由于没有重写D::f(int),在D2中变不可见       {            std::cout << __FUNCTION__ << std::endl;       }   //  virtual void fun() // error! 基类的此虚函数被指定为最终,不能被重写,虽然没有显示指定"override"   //  {   //      std::cout << __FUNCTION__ << std::endl;   //  }   //  virtual void fun() override // error! 基类的此虚函数被指定为最终,不能被重写   //  {   //      std::cout << __FUNCTION__ << std::endl;   //  }    };      int _tmain(int argc, _TCHAR* argv[])   {       D2 d2;       D d1;       B *b = &d1;       b->f();      // B::f       b->fun();    // D::fun   //  d1.f();     // error! B::f在D中不可见       d1.f(10);   // hiding: D::f   //  d2.f(10);   // error! D::f(int)在D2中不可见       d2.f();     // D2::f       d2.fun();   // D::fun          return 0;   }  

    3.避免滥用setter方法

    4.方法优于字段

    5.尽可能用namespace来公开功能

    6.赋予对象创建者更多权利

    7.避免暴露深层次的继承

    继承只是增加功能,尽量不重写功能
    转载请注明原文地址: https://ju.6miu.com/read-402.html

    最新回复(0)