2011-10-06 131 views
0

我正在开发一个项目,其中我使用了许多类。 创建类的我已经使用了新的运营商......例如,在香蕉类我有苹果类的实例变量......减少内存使用量

这是我想说的&按比例缩小的陈述并不代表编码字 - 字......所以,请不要点语法错误......但要尽量理解头文件的方法

(banana.h):

static int counter = 0; 
class banana 
{ 
    public: 
    apples *ap_obj;//(apple is a class defined another file apples.cpp) 
    int *index; 
} 

in banana.cpp:

class banana 
{ 
    banana::banana(void) 
    { 
    ap_obj = new apples; 
    index = new int; 
    *index = ++counter; 
    } 
}; 

我的第一个问题是,我的方法在记忆效率方面是否正确? (我知道我没有任何运行时错误肯定)

我的第二个问题是,我想访问一个香蕉对象在我的任何类的方法之一,通过使用索引(请注意,每香蕉对象具有唯一索引)变量。 为此,我想使用另一个类的注册表(因为我想存储许多类的对象的索引)。 我想存储任何类的第一个对象的指针在我的注册表类中。 &用于访问类的任何第n个对象的指针,我打算使用索引变量的第一对象上使用指针arithmatics ...例如

class registry 
{ 
    banana *base_obj;//this value will be initialised when i create the 1st object of banana class 
    banana *registry::get_nth_object(int shift); 
    { 
    return *(base_obj + shift);//shift is the index variable of banana class 
    } 
}; 

在任何其他类别i可以只调用get_nth_object &传递我想要的指针对象的索引号&我会得到那一点。

我的代码有什么问题吗? 或者如果有什么可以改善,请帮助我。

供参考我使用http://www.cplusplus.com。 我是一个机甲ENGG学生,所以请原谅我,如果我做任何愚蠢的错误

+2

您可以通过使用矢量而不是数组/指针来改善它。 – RvdK

回答

0

首先,你应该找出你的香蕉 - >苹果关系是什么样的关系。如果它是一种作品(一种香蕉由苹果和...组成),最简单的想法是将一个苹果实例存放在香蕉中。

class banana 
{ 
    apple apple_; // a banana HAS A apple 
}; 

如果这是真的,但你必须香蕉无数并有一个数字,一个平等的,你可以实现Flyweight Pattern安全存储器使用的苹果。但是你不应该这样做,因为你认为你有一个记忆问题,但是因为你测量出你有一个苹果记忆问题。

如果您的关系更多是共享所有权,您应该在香蕉中存储一个指向Apple实例的指针,并考虑在哪里存储苹果对象。最简单的方法是存储std::shared_ptr<apple>并让参考计数器控制苹果的使用寿命。

第二个问题是如何存储和访问香蕉物体。我会介绍一个BananaRepository,它负责存储和检索香蕉。

class BananaRepository 
{ 
    typedef XYZType BananaID; 
    Banana& GetByID(BananaID id); 
    BananaID Add(Banana& b); 
}; 

您应该抽象使用的ID和存储类型,以便客户端代码不依赖于该详细信息。每个香蕉都有一个ID,我可以使用这个ID从存储库中获得一个香蕉。最简单的实现是Banana :: ID = vector :: size_type和BananaRepository中的一个向量。

class BananaRepository 
{ 
public: 
    typedef std::vector<Banana>::size_type BananaID; 

    Banana& GetByID(BananaID id) 
    { 
    return bananas_.at(id); 
    } 

    BananaID Add(Banana& b) 
    { 
    bananas_.push_back(b); 
    return bananas_.size() - 1; 
    } 

private: 
    std::vector<Banana> bananas_; 
}; 
0

我知道,我没有肯定

那么任何运行时错误,看来你运行时错误(或更多)。声明

int *index; 

index为未初始化的指针,并

*index = ++counter; 

提出的counter内容到index点(这是完全不确定的地方,这可能是)的地方。当然,这将是一个奇怪的错误的原因。

也许你想申报

int index; 

index = ++counter; 

我承担?

3

直接嵌入的内存更有效的(这样可以节省你的指针双方的开销和一个堆分配,提高访问的局部性):

class banana 
{ 
    private: 
    apples ap_obj; 
    int index; 
} 

请注意,您在忘记new指数你的原始代码。我甚至不确定我是否了解它的需求。是只有用于找到一个特定的banana?如果是这样,它应该不是banana的成员。为什么还要存储索引?引用特定实例的常用方法是使用banana*

+0

+1,但你应该解释他为什么:-)它不应该是一个“ipse dixit”:-) :-)(也许​​你应该告诉他,与默认拷贝构造函数有区别,并且需要删除if他使用了一个指针......并且可能还有许多其他的东西) – xanatos

+0

@xanatos:好点,完成。 – MSalters

+0

是的,我忘了把新的索引。让我纠正它。 –

0
  1. 对于存储标量数据,您不需要使用指针。这就是为什么int index。指定一些“不可能”的值来知道索引是非法的。

  2. 你的方法get_nth_object是错误的。您不能确定所有banana's都分配在一致的内存块中。因此,您不能使用这种线性地址算法来获取对象。查找有关使用动态数组或列表的信息。在阵列的情况下,您可能想检查有关超载订阅运营商的信息

1

首先,香蕉构造函数本身的语法不正确。它不应该被文本类香蕉包围{};使用新的堆

第二,分配内存将是你需要做的不够快。你不应该以任何其他方式做它(即不要使用malloc)。所以你在这方面很好。

至于你的注册表例如,如果你所有的香蕉实例在连续的内存区域被分配get_nth_object只会工作....东西你没有,当你使用新分配内存的控制。如果你使用新的香蕉[大小]为香蕉指针分配内存,那会更好,并且内存将是连续的。

即使你没有让他们都经常在内存中间隔,如果你需要删除一个香蕉?还是两三个?还是半打?很快你会做一些真正的紧张记录保持事情的工作。

我自己更喜欢在它的构造函数创建时为其中的每个香蕉分配一个唯一的ID,并且在香蕉的构造函数中插入一个像地图这样的关联容器(即std :: map)(在代码中使用#include )。我将使用唯一的ID作为关键字,然后您可以使用指向香蕉的指针作为值。在香蕉的析构中,我会让香蕉从注册表中移除。

你的注册表将负责所属关联容器(即地图)。