减少内存使用量

时间:2011-10-06 11:20:28

标签: c++

我正在开发一个项目,其中我使用了很多课程。 为了创建类,我使用了new运算符...例如,在banana类中,我有一个类apple的实例变量......

这是我想要说的一个缩小的代表性&没有代表这个代码的字样......所以请不要指出语法错误......但是要理解方法论

在头文件(banana.h)中:

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

在banana.cpp中:

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

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

我的第二个问题是,我想通过使用索引(plz注意每个香蕉对象具有唯一索引)变量来访问任何类的一个方法中的香蕉对象。 为此,我正在考虑使用另一个类注册表(因为我想存储许多类的对象的索引)。 我正在考虑将任何类的第一个对象的指针存储在我的注册表类中。 &安培;为了访问类的任何第n个对象的指针,我计划使用索引变量在第一个对象上使用指针算术...示例

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
  }
};

在任何其他课程中我都可以致电 get_nth_object &传递指针我想要的对象的索引号&我会明白这一点。

我的代码有什么问题吗? 或者如果有任何改进可以帮助我。

参考我使用http://www.cplusplus.com。 我是一名机械工学生,所以请原谅我,如果我犯了任何愚蠢的错误

5 个答案:

答案 0 :(得分:3)

直接嵌入更节省内存(它可以节省指针和堆分配的开销,并提高引用的局部性):

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

请注意,您忘记了原始代码中的new索引。我甚至不确定我是否理解它的必要性。仅使用 来查找特定的banana吗?如果是这样,它根本不应该是banana的成员。为什么还要存储索引呢?引用特定实例的常用方法是使用banana*

答案 1 :(得分:1)

首先,香蕉构造函数本身的语法不正确。它不应该被文本类banana {};

包围

其次,使用new在堆上分配内存将足够快,以满足您的需要。你不应该以任何其他方式这样做(即不要使用malloc)。所以你在这一点上很好。

至于你的注册表示例,get_nth_object只有在你的所有香蕉实例都分配到连续的内存区域时才会起作用....你在使用new分配内存时无法控制。如果你使用新的香蕉[size]为你的香蕉指针分配内存会更好,并且内存将是连续的。

即使你确实在内存中定期间隔它们,如果你需要删除香蕉怎么办?还是两三个?还是打了半打?很快你就会做一些真正强烈的记录保持工作。

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

您的注册表将负责拥有关联容器(即地图)。

答案 2 :(得分:0)

  

我知道我确实没有任何运行时错误

好吧,似乎你运行时错误(或更多)。声明

 int *index;

index作为未初始化的指针,然后

 *index = ++counter;

counter的内容放到index指向的位置(这可能是完全未定义的位置)。当然这会导致奇怪的错误。

也许你想申报

  int index;

 index = ++counter;

我假设?

答案 3 :(得分:0)

  1. 要存储标量数据,您不需要使用指针。这就是int index的原因。分配一些“不可能”的值来知道索引是非法的。

  2. 您的方法get_nth_object错误。您无法确定是否在一致的内存块中分配了所有banana's。因此,您不能使用这种线性地址算法来获取对象。查找有关使用动态数组或列表的信息。如果是数组,您可能需要检查有关重载订阅运算符的信息

答案 4 :(得分:0)

首先,你应该找出你的香蕉与苹果关系是什么类型的关系。如果它是一种成分(香蕉由其苹果和......组成),最简单的想法是将苹果实例存放在香蕉中。

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

如果这是真的,但你有无数的香蕉,并且有许多苹果等于你可以实现Flyweight Pattern安全内存使用。但是你不应该这样做,因为你认为你有记忆问题,但是因为你因为苹果而导致记忆问题。

如果您的关系更多是共享所有权,则应该在apple中存储指向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_;
};