2011-02-07 52 views
2

关于C++的设计和效率的问题...想象一下这样的代码 -高效创建大量小C++对象的需要访问“全局”对象

Database db; 

class SmallObject 
{ 
private: 
    /* Some small amount of data and functions */ 
public: 
    /* Constructor, more functions */ 
    void fn1() { /* Code that uses global db to do it's job */ } 
    void fn2() { /* Code that uses global db to do it's job */ } 
    void fn3() { /* Code that uses global db to do it's job */ } 
    void fn4() { /* Code that uses global db to do it's job */ } 
}; 

这很好,高效,效果很好。但是数据库是全局状态,这是不好的。它使得非常难以独立地测试类,并且意味着SmallObject依赖于数据库的特定实现。

所以我重组它是这样的: -

class SmallObject 
{ 
private: 
    /* Some small amount of data and functions */ 
public: 
    SmallObject(Database& db) { db_ = db; } 

    void fn1() { /* Code that uses global db_ to do it's job */ } 
    void fn2() { /* Code that uses global db_ to do it's job */ } 
    void fn3() { /* Code that uses global db_ to do it's job */ } 
    void fn4() { /* Code that uses global db_ to do it's job */ } 
}; 

也许会让一个工厂来创建他们,所以我可以粗略像以前一样使用它们。

class SmallObjectFactory 
{ 
private: 
    Database* db_; 
public: 
    SmallObjectFactory() 
    { 
     db_ = new SpecificDatabaseSubclass; 
    } 

    SmallObject* create() { return new SmallObject(db_); } 
}; 

这也意味着我的SmallObject不再与确切的数据库实现耦合,但仍然方便使用。

但是,假设有10000个SmallObject实例。现在每个人都有一个指向的数据库对象在那里。这是可怕的低效率,也不觉得重复数据这么多次是好设计...

那么,是否有一些模式在C + +,允许我不使数据库全局,但让我不要在每个SmallObject实例中存储重复数据?

这是专门C++模板等等等等,都很好...

+1

什么让你觉得有很多指针的一个对象是无效的?唯一重复的是数据库对象的内存地址,这个地址很小。 – SirDarius 2011-02-07 15:13:39

+0

我同意SirDarius,你只会使用4-8字节/指针(取决于你的架构)。所以你只需要为10,000个对象使用40-80k的额外字节。也许如果你创造了数百万的这些物体,这将是一个问题。 – GWW 2011-02-07 15:16:08

+0

也许这是一个不好的例子。这不是绝对的内存量,但它可能会使我的对象使用量增加一倍。更有甚者,似乎无用地在我的对象的每一个实例中存储相同的值,并且想知道是否有任何合理的方法来避免那些没有发生在我身上的东西。 – jcoder 2011-02-07 15:17:17

回答

1

如果您正在寻找效率,它可能就是您分配大量小对象的方式,并且可能需要使用某种池。

关于数据库,我会质疑你的耦合以及你的类的用户在做什么和看到什么。理想情况下,你不希望他们看到你的实现细节,如果你的类拥有这个私有的“数据库”成员,虽然你可以正向声明它,但这可能是一个问题。

你的构造应该是这样的:

explicit SmallObject(Database& db) : db_(db) {} 

你也应该处理SmallObjectFactory妥善管理的基本分贝构件的寿命,可能使你的类不可复制或使用shared_ptr的。

您的其他选项可能是维护一个小对象集合并执行通过容器而不是对象访问数据库的功能。这是一种常见的设计模式,但取决于您的模型。

1

你说10000个实例,然而一个32位系统,只会是这样的内存40K上。除非你在嵌入式环境下工作,否则我会建议在每个实例中存储指针,就像你在第二个例子中演示的那样。

这也使您能够灵活地在不同的对象实例上插入不同的数据库,从而启用其他未来的功能。

2

您可以在SmallObject类中定义一个静态db属性,并在运行时为其分配数据库。然后,SmallObject的所有实例都可以使用此属性,而不需要指向它的指针的副本。

2

如果我记得正确,模式称为FlyWeight。

只需将数据库作为参数传递给每个方法即可。

这交换了一些执行效率,方便和保证,少一些内存使用。

干杯&心连心,