根据输入初始化特定的子类

问题描述:

我想根据用户是否用-m或-f调用程序来初始化特定的子类。根据输入初始化特定的子类

我写的界面是这样的:

class DatabaseInterface { 

    public: 
    virtual std::vector<Newsgroup> list_newsgroups() = 0; 
    virtual std::vector<Article> list_articles(const size_t article_id) const = 0; 
    virtual bool create_newsgroup(const std::string& newsgroup_name) = 0; 
    virtual bool create_article(const size_t newsgroup_id, const std::string& title, const std::string& author, const std::string& text) = 0; 
    virtual bool delete_newsgroup(const size_t newsgroup_id) = 0; 
    virtual std::pair<int,Article> get_article(const size_t newsgroup_id, const size_t article_id) const = 0 ; 
    virtual int delete_article(const size_t newsgroup_id, const size_t article_id) = 0; 
}; 

在我的类,它使用的数据库,我有这些行:

string file_memory; 
DatabaseMemory db; 
try { 
    file_memory = argv[2]; 
    if(file_memory.compare("-file") == 0 || file_memory.compare("-f") == 0) { 
    DatabaseFile db; 
    cout << file_memory << endl; 
    } else if (file_memory.compare("-memory") == 0 || file_memory.compare("-m") == 0) { 
     DatabaseMemory db; 
    } else { 
    cerr << "Specify saving on disk with '-f' or in memory with '-m' " << endl; 
    exit(1); 
    } 
    } catch (exception& e) { 
    cerr << "Specify saving on disk or in memory" << endl; 
    exit(1); 

}

正如你所看到的我试图初始化派生的DatabaseMemory,只是为了讨好编译器,但是,这看起来像是一种劣质的方法。我会如何改善这一点?

我希望能够写类似

DatabaseInterface db; 
if(file_memory == "-m") { 
    db = DatabaseMemory(); 
} else if (file_memory == "-f") { 
    db = DatabaseFile(); 
} else { 
exit(1); 
} 
//.... do stuff 

我如何去这样做呢?在这一点上,我的界面没有给我任何东西。我想我可能错过了在这里使用它的要点。

您需要间接(即指向基类的指针或引用)来支持多态。喜欢的东西

std::unique_ptr<DatabaseInterface> db; 
if (file_memory == "-f") { 
    db = std::make_unique<DatabaseFile>(); 
} else if (file_memory == "-m") { 
    db = std::make_unique<DatabaseMemory>(); 
} 

如果你不使用C++ 14的是,你可以用

db.reset(new DatabaseFile); 
+0

由于更换make_unique,会尝试。虽然,它不应该与make_unique相反吗?例如,如果“-f”则使DatabaseFile具有唯一性,反之亦然?问候 – enrm 2015-04-02 12:53:39

+0

@enrm:这会更有意义。我只是复制了最终代码片段中的标志,而没有太多考虑它们可能的含义。 – 2015-04-02 13:16:56

+0

使用make_unique需要什么编译器?我使用g ++ 4.9.2,它不能识别make_unique .. – enrm 2015-04-02 13:37:32