如何关联通过抽象工厂创建的无关对象

时间:2015-03-07 13:58:06

标签: c++ design-patterns

目前我正在开发一个处于初始阶段的设计,下面是我迄今为止做过的一些功课,但它似乎没有问题,而且我一直面临着一些问题。从下面的代码可以清楚地看出,设备工厂已经用于设备对象和库对象的创建目的。 现在的工作是从工厂获取设备对象后,将调用connect函数,这将确保连接成功完成,现在需要使用任何相关的解析器(XML,JSON或其他支持的解析器)来获取数据。现在这里的任务(设备和库的选择)都是单独完成的,所以现在的工作是我需要在选定的对象上强加选定的库,并且对于相同的赋值操作符已经在Device类中重载但是我收到错误"不能转换'图书馆*'到设备*'在任务"将库对象分配给设备对象时。除此之外,我还需要使用Library类作为抽象类,这在当前实现中是不可能的。

#include<iostream>
#include<string.h>

using namespace std;

class Library
{
public:
    virtual void lib_func();
    virtual ~Library(){}
};

class JSON : public Library
{
public:
    void lib_func()
    {
        cout<<"connect through USB"<<endl;
    }
};

class JXML : public Library
{
public:
    void lib_func()
    {
        cout<<"Connect through TCP"<<endl;
    }
};

class XML : public Library
{
public:
    void lib_func()
    {
        cout<<" connect through BT"<<endl;
    }
};

class Device
{
public:
    virtual void connect()=0;
    const Device& operator =(const Device& obj);
    virtual ~Device(){}
private:
    Library * obj;
};

const Device& Device:: operator =(const Device& rhs)
{
    Library *objorig=obj;
    obj=new Library(*rhs.obj);
    delete objorig;
    return *this;
}

class D1: public Device
{
public:
    void connect()
    {
        cout<<" connect through USB"<<endl;
    }
};

class D2 : public Device
{
public:
    void connect()
    {
        cout<<"Connect through TCP"<<endl;
    }
};

class D3 : public Device
{
public:
    void    connect()
    {
        cout<<" connect through BT"<<endl;
    }
};

class Devicefactory
{
public:
    virtual Device* create_instance(const char* type)=0;
    virtual Library* populate_library(const char* type)=0;
};

class factory : public Devicefactory
{
public:
    Device* create_instance(const char* type)
    {
        if(!strcmp(type,"D1"))
        {
            return new D1();
        }
        else if(!strcmp(type,"D2"))
        {
            return new D2();
        }

        else if(!strcmp(type,"D3"))
        {
            return new D3();
        }
        return NULL;
    }

    Library* populate_library(const char* type)
    {
        if(!strcmp(type,"XML"))
        {
            return new XML();
        }
        else if(!strcmp(type,"JSON"))
        {
            return new JSON();
        }
        else if(!strcmp(type,"JXML"))
        {
            return new JXML();
        }
        return NULL;
    }
};

int main()
{
    Devicefactory *obj=new factory;
    Device * object = obj->create_instance("D3");
    Library *object1 = obj->populate_library("JSON");
    object->connect();
    object=object1;
    object->lib_func();
    delete object;
    delete obj;
    return 1;
}

3 个答案:

答案 0 :(得分:0)

我可能遗漏了一些内容,但在我看来,您只需要向setLibrary添加Device成员函数:

void setLibrary(Library* library) { 
    obj = library; 
}

然后在你的main函数中使用它:

Device* object = obj->create_instance("D3");
Library* object1 = obj->populate_library("JSON");
object.setLibrary(object1);

我假设设备不应该拥有该库,而您只是想将该库与设备相关联。

无需编写赋值运算符。

您可能打算在lib_func中提取Library摘要:

virtual void lib_func() = 0;

偏离主题:我建议您从工厂返回std::unique_ptr而不是原始指针,这样您就不必记得拨打delete(您忘了删除{ {1}})。没有理由使用Library分配工厂,你可以在堆栈上创建它。

答案 1 :(得分:0)

使用私有继承来实现相同的功能,这样就可以覆盖Device类中的虚函数lib_info并实现相同的功能。除了这种方法之外,您的Library类将是抽象的.Below是您需要使用的方法来避免任何赋值错误。通常,私有继承用于覆盖组合不可能的虚函数。 第1步:覆盖Device类中的lib_func。

class Device : private Library
{

public:

virtual void connect()=0;
void lib_func();
virtual ~Device(){}


};

第2步: 下面是重写函数的实现

void Device :: lib_func()     {

Devicefactory * obj =新工厂;

 Library *object1=obj->populate_library("JSON");
 object1->lib_func();

 }

第3步: 现在你只需要在驱动程序函数中使用Device对象,这就是类 抽象。

int main()
  {

  Devicefactory *obj=new factory;

   Device * object=obj->create_instance("D3");

    object->connect();

     object->lib_func();

    delete object;

    delete obj;

    return 1;

    }

答案 2 :(得分:0)

Below is the approach which is implemented  through without assignment operator and private inheritance.

#include<fstream>
#include<iostream>
#include<string.h>
#include<memory>
#define RESULT_ERROR 0
#define RESULT_SUCCESS 1 
using namespace std;

   class Library
   {

    public:

    virtual void lib_func(fstream &obj)=0;

    virtual ~Library(){}

    };

     class JSON : public Library

    {

    public:

    void lib_func(fstream &obj)

    {

    cout<<"using json to fetch the object"<<endl;

    }

    }; 

    class JXML : public Library

    {

    public:

    void lib_func(fstream &obj)

    {

    cout<<"using JXML to fetch the object"<<endl;

    }

    };

    class XML : public Library

    {

    public:

    void lib_func(fstream &obj)

    {

    cout<<"use XML to fetch the data"<<endl;

    }



    }; 


    class Device 
    {

    public:
    Device( Library *lib=NULL) : lib(lib){}
    virtual void connect()=0;

    int16_t  impose_library(fstream &obj);
    virtual ~ Device(){}
    protected:
    Library *lib;

    };

 class D1: public Device
   {

    public:
     D1():Device(lib)
      {

      }
    void connect()

    {

    cout<<" connect through USB"<<endl;

    }

    }; 

    class D2 : public Device

    {

    public:
 D2():Device(lib)
      {

      }
    void connect()

    {

    cout<<"Connect through TCP"<<endl;

    }



    };

    class D3 : public Device

    {

    public:
    D3():Device(lib)
      {

      }
    void  connect()

    {

    cout<<" connect through BT"<<endl;

    }



    }; 



class Devicefactory 

{

public:

virtual Device* create_instance(const char* type)=0;

virtual Library* populate_library(const char* type)=0;

};

class factory : public Devicefactory 

{

public:

Device* create_instance(const char* type)

{

      if(!strcmp(type,"D1"))

       {

           return new D1();

       }  

       else if(!strcmp(type,"D2"))

       {

           return new D2();

       } 



       else if(!strcmp(type,"D3"))

       {

           return new D3();

       } 

       return NULL; 

    }



  Library* populate_library(const char* type)

  {

      if(!strcmp(type,"XML"))

       {

           return new XML();

       }  

       else if(!strcmp(type,"JSON"))

       {

           return new JSON();

       } 



       else if(!strcmp(type,"JXML"))

       {

           return new JXML();

       } 

       return NULL; 

    }



};

     int16_t Device :: impose_library(fstream &fconfig)
    {

   std::unique_ptr <Devicefactory> obj (new factory);
   std::unique_ptr<Library> object1 (obj->populate_library("JSON"));
    if(object1!=NULL)
     {
     object1->lib_func(fconfig);
     return RESULT_SUCCESS;
     }

     else
     {
       return RESULT_ERROR;

     }

}
    int main()

    { 

  int16_t  result;
  fstream  fconfig  ;

   std::unique_ptr<Devicefactory> obj (new factory);

 std::unique_ptr<Device> object(obj->create_instance("D3"));

     object->connect();

     result=object->impose_library(fconfig);
     if(result==RESULT_ERROR)
     {
       cout<<"NULL object"<<endl;
     }

    return 1;

    }