单例模式的出现意义在于,我们一个class只想要其有一个对象,我们直接看示例代码
#include
using namespace std;
class singleton{
private:
//make default constructor unable to access from outside of class
singleton(){};
static singleton* instance;
public:
singleton(singleton const &) = delete;
static singleton* getinstance();
};
singleton* singleton::instance = nullptr;
singleton*
singleton::getinstance(){
if(!instance){
instance = new singleton;
}
return instance;
}
int
main()
{
singleton* simple_singleton_1 = singleton::getinstance();
singleton* simple_singleton_2 = singleton::getinstance();
cout << "simple_singleton_1 is " << simple_singleton_1 << " simple_singleton_2 is " << simple_singleton_2;
return 0;
}
上述的代码我们没有显示的示例化的操作(就算有也会被编译器报错,因为我们明确的禁止外部进行默认的构造),我们还要明确一点我们的class的prototype存于code区域(text),而不是stack,所以我们可以执行getinstance()
方法,但是我们执行的时候要明确指明范围也就是singleton::
,并且我们的getinstance()
创造的对象(obj指针变量,obj本来的数据还在stack中)存于data区域中,我们的class如果再创建一个对象还是要走getinstance()
方法,我们的getinstance()
方法的第一行是一个条件判断,发现singleton::instance
不为空,那么就不会通过条件判断直接返回data区域中已经存在的obj指针变量(也就是第一个创建的obj地址)
为什么创建obj的方法也要static?因为我们想等实例化后obj对应的static方法放入到data区域中,假如我们不加static那么就会在stack中
最后看运行结果
simple_singleton_1 is 0x55e4334e8eb0 simple_singleton_2 is 0x55e4334e8eb0
工厂模式顾名思义就是将我们的类像工厂一样生产东西,比如我们一个工厂有三个流水线分别生产三个不同的产品,所以一个工厂类可以更具我们的需求生产不同的对象(在类实例化成对象的时候更具需求实例成不同的对象),工厂模式又分为多个类别
直接看代码
#include
using namespace std;
enum CARTYPE {byd_type, tesla_type};
class car{
public:
virtual void echo() = 0; //什么类型的car
virtual ~car(); //为了安全,确保car的派生类对象赋值给car时,在销毁的时候会调用派生类本身的析构函数
};
class tesla : public car{
public:
void echo(){ cout << " i am tesla " << endl; }
~tesla();
};
class byd : public car{
public:
void echo(){ cout << " i am byd " << endl;}
~byd();
};
class factory{
public:
car* create_car(CARTYPE type);
};
car*
factory::create_car(CARTYPE type){
switch(type){
case byd_type:
return new byd();
break;
case tesla_type:
return new tesla();
break;
default:
return nullptr;
break;
}
}
int main()
{
factory f;
auto cars = f.create_car(byd_type);
cars->echo();
return 0;
}
看了上述代码我们会发现简单工厂会非常好理解,但是有一些细节比如为什么我们将派生类(byd,tesla)赋值给基类(car)的时候我们的car的析构函数要加上virtual
关键字?这个请看这里