数据结构以容纳多种数据类型C ++ [英] Data Structure to hold multiple data types C++

查看:83
本文介绍了数据结构以容纳多种数据类型C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,有一个类(即ItemData类),该类具有30多个不同类型的成员变量,例如

In my application there is a class (i.e. ItemData Class) which has more than 30 member variables of different types such as

int a;
int b;
std::string c;
float d;
double e;
double f;
char * g;

还有更多

我的应用程序需要创建大量的itemdata类,以便该应用程序的内存使用率很高.有关此类的一个特殊事实是,大多数ItemData类的实例仅具有几个成员变量的值.

My application needs to create large number of itemdata classes so that memory usage of the application is high. One special fact about this class is most of the instances of ItemData class has values for few member variables only.

Ex:实例一可能仅具有a和b的值.实例2只能具有b,c和g的值.

Ex: Instance one may have values for a and b only. Instance two can have values for b,c and g only.

因此,为减少我的应用程序的内存使用量,我需要一种方法来仅为创建实例时具有数据的成员变量分配内存.因此,尽管我具有通用的数据结构,该结构可以通过位置访问元素并在其上存储数据.因此,ItemData类具有如下所示的内容,并在其上存储动态分配的数据.(我必须分别保持位置和每个位置上的信息保持不变)

So to reduce the memory usage of my application, I need way to allocate memory only for member variables which has data when the instance is creating. So I though of having generic data structure which can access elements via position and store data on that. So ItemData class has something like below and store dynamically allocated data on that.(I have to maintain the position and information hold on each position seperately)

std::vector<void*> vec_DataArray;

如果ItemData实例mItemData1具有a和d的值:

If ItemData instance mItemData1 has values for a and d:

mItemData1.vec_DataArray[0] = new int(iValue);
mItemData1.vec_DataArray[3] = new float(fValue);

有人可以让我知道这是否是减少应用程序内存使用的好方法吗?是否有通用容器可以容纳多种数据类型(用于vec_DataArray),以便在访问数据时避免void *到数据类型的转换.

Can someone let me know whether this is a good approach to reduce the memory usage in my application? Is there any generic container which can hold multiple data types (for vec_DataArray) so that I can avoid void* to datatype conversion when accessing data.

推荐答案

我认为您应该避免使用可以容纳多种类型数据的数据结构,并考虑采用其他设计.

I think you should avoid using a data-structure that can hold multiple types of data if you can and consider a different design.

例如,您可以考虑使用类似 Flyweight模式的东西,然后将外部" ItemData 类中的"状态,仅保留内部"状态.对我来说,它有点面向对象,但它可能满足您的需求.例如,您可以保留从项目索引到数据的单独映射.这是否对您的内存使用有所帮助取决于数据的稀疏程度.

For example you could consider using something a bit like the Flyweight pattern and pull the "extrinsic" state out of the ItemData class leaving only the "intrinsic" state. It feels a bit non object-oriented to me but it might meet your needs. For example you could keep separate maps from item index to data. Whether this will help with your memory usage depends on how sparse your data is.

#include <unordered_map>
#include <iostream>

class Item {
 private:
  std::string type_;  // "intrinsic" state
 public:
  Item(const std::string &type) : type_(type) {} 

  // pass in "extrinsic" state
  void someOperation(std::string color, double speed) {

    // do something using both "intrinsic" and "extrinsic" state...
    std::cout << color << " " << type_ << " moving at " << speed << "mph\n";
  }
};

class AnimalSim {
 private:
  std::unordered_map<int, std::string> duck_colors_;   // Store extrinsic
  std::unordered_map<int, std::string> sheep_colors_;  // state separately
  std::unordered_map<int, double>      duck_speeds_;   // in a more
  std::unordered_map<int, double>      sheep_speeds_;  // efficent way.
 public:
  void run();
  std::string getDuckColor(int duck_index) const;
  std::string getSheepColor(int sheep_index) const;
  double      getDuckSpeed(int duck_index) const;
  double      getSheepSpeed(int sheep_index) const;
};

void
AnimalSim::run() {
  auto duck = Item{"duck"};    // Create `Flyweight` objects that can be shared.
  auto sheep = Item{"sheep"};  // Should probably be done by a factory with a cache.

  // Create duck 0
  duck_colors_.emplace(0, "red");
  duck_speeds_.emplace(0, 150.0);

  // Create duck 1 - has no speed
  duck_colors_.emplace(1, "green");
  size_t num_ducks = 2;

  // Create sheep 0 - has no color
  sheep_speeds_.emplace(0, 100.0);
  size_t num_sheep = 1;

  // Do something with all the ducks
  for(size_t i = 0; i != num_ducks; ++i)
    duck.someOperation(getDuckColor(i), getDuckSpeed(i));

  // Do something with all the sheep
  for(size_t i = 0; i != num_sheep; ++i)
    sheep.someOperation(getSheepColor(i), getSheepSpeed(i));    
}

std::string
AnimalSim::getDuckColor(int duck_index) const {
  auto color_itr = duck_colors_.find(duck_index);
  return color_itr != duck_colors_.end() ? color_itr->second : "black"; 
}

std::string
AnimalSim::getSheepColor(int sheep_index) const {
  auto color_itr = sheep_colors_.find(sheep_index);
  return color_itr != sheep_colors_.end() ? color_itr->second : "white"; 
}

double
AnimalSim::getDuckSpeed(int duck_index) const {
  auto speed_itr = duck_speeds_.find(duck_index);
  return speed_itr != duck_speeds_.end() ? speed_itr->second : 0.0; 
}

double
AnimalSim::getSheepSpeed(int sheep_index) const {
  auto speed_itr = sheep_speeds_.find(sheep_index);
  return speed_itr != sheep_speeds_.end() ? speed_itr->second : 0.0; 
}

int main() {
  AnimalSim animal_sim;
  animal_sim.run();
}

实时演示.

编辑:我看到您正在从数据库中加载数据.在哪种情况下,我想知道为什么您不只在需要时从数据库中按需加载?

Edit: I see you are loading data from a database. In which case I wonder why you are not just loading-on-demand from the database when you need to?

这篇关于数据结构以容纳多种数据类型C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆