1

所以我有一个“大”类A,另一个类B将包含至少 100 个对象的向量AB将类中的所有对象存储为a 似乎不是一个好主意,vector<A>因为可以重用很多信息。

我正在考虑在类中有一个模板,B它包含所有相似的属性,A然后创建一个vector<A*>。但这使他们都一样...

那么有没有一种方法可以存储类的相似变量,以便只需要多次存储少数差异?

最小的工作示例

#include <iostream>

// suppose an int is big:
struct A { // create struct which holds 3 ints
    A() : a(0),b(0),c(0) {} //ctor

    void print() { // print all variables
        cout << a << ", " << b << ", " << c << endl;
    }
    int a,b,c;
};

class B { // create object that holds a vector of A
public:
    B(int vectorSize) {
        vector_A.resize(vectorSize);
        vector_ptr_A.resize(vectorSize);
    }

    void initValues() {
        ///////////////////////////////////////
        // METHOD 1
        vector_A.resize(vectorSize); // resize 
        for (int i=0; i<vector_A.size(); ++i) {
            vector_A[i].a = rand() % 100; // randomize A::a
            vector_A[i].b = 5;            // only B wants A::b to be 5
            vector_A[i].c = 10;           // only B wants A::c to be 10
        }
        ///////////////////////////////////////

        ///////////////////////////////////////
        // METHOD 2
        A_template.b = 5;  // only B wants A::b to be 5
        A_template.c = 10; // only B wants A::c to be 10
        vector_ptr_A.resize(vectorSize,&A_template); // point to template
        for (int i=0; i<vector_ptr_A.size(); ++i) {
            vector_A[i].a = rand() % 100; // randomize A::a
        }
        ///////////////////////////////////////
    }

    void print1() { // prints vector_A[i]
        for (int i = 0; i < vector_A.size(); ++i) {
            vector_A[i].print();
        }
    }
        void print2() { // prints vector_ptr_A[i]
        for (int i=0; i < vector_ptr_A.size(); ++i) {
            vector_ptr_A[i]->print();
        }
    }

    // method 1
    vector<A> vector_A; // a big, big vector

    // method 2
    A A_template;
    vector<A*> vector_ptr_A; // all the same
};

int main() {
    srand( time(NULL) );
    B b(10);
    b.initValues();

    cout << "METHOD 1\n";
    b.print1();             // as desired, but inefficient
    cout << "\nMETHOD 2\n";
    b.print2();             // all the same output
}

编辑

一些澄清,因为最小的工作示例有点令人困惑。我现在也对其进行了调整以使其更加清晰。

类的成员A是由B用户设置的。例如,用户将为A::a向量的每个元素(由随机数表示)定义,而其他 2 个(A::bA::c)由 定义B。类A不仅是由 使用的类B,还由用户或任何其他类使用。

所以基本上我要求一种方法,所以我不必为向量的每个元素设置A::b和,而只需要一次。对于我应该设置的每个元素都是不同的。A::cA::a

为了说明我想要这个的原因:类A在我的程序中是一个Sprite类,并且B必须能够将精灵打印为图块并命名为TileMap. 因此,向量中TileMap的很多Sprites 都可以在窗口上绘制,但是对于所有这些图块(纹理图块大小、绘图图块大小、纹理文件等),很多信息都是完全相同的,而我没有想要为每个图块设置所有这些变量。我想创建某种模板,可用于Sprite向量中的每一个。这种方式不仅更容易,占用空间更少,而且更安全:我知道所有这些值将完全相同。

4

3 回答 3

1

需要进行一些澄清,但我会理解你的问题。

struct Common_A_Members
{
  int x;
  double y;
};

struct Uncommon_A_Members
{
  unsigned int this_member_changes;
};

struct A : public Common_A_Members, public Uncommon_A_Members
{
  A(const Common_A_Members& c, const Uncommon_A_Members& d)
  : Common_A_Members(c), Uncommon_A_Members(d)
  { ; }
};


struct B
{
  Common_A_Members a_common;
  std::vector<Uncommon_A_Members> a_uncommon;
};

在上面的例子中,概念类被分成两部分,一部分包含不改变的值(Common_A_Members)和改变的值(Uncommon_A_Members)。这允许B拥有一个常量数据成员和一个数据向量changing。概念类有一个构造函数,A它结合了常量数据和变化的数据。

其中的两个成员B是一组。对于那些具有不同常量值的概念类,需要复制或重复该集合。

该理论是从变化的数据中分解出恒定的数据。

于 2013-03-17T18:07:09.513 回答
1

如果变量 b,c 对于 A 的所有实例总是相同的 - 使它们在 A 中是静态的。

如果变量 b,c 对于存储在 B 的一个实例中的 A 的一组实例相同,请考虑将 b,c 放在 B 中。

如果变量 b,c 仅对于某些 A 集合相同,请考虑将 b,c 分解为它自己的“配置”类 C,并将指向 C 的智能指针存储在 A 中。这假设 b,c 足够大或共享在足够多的情况下,额外的管理是值得的。

顺便说一句,你确定你的 print2() 函数应该使用 vector_ptr_A[0] 而不是 vector_ptr_A[i]?(如果可以的话,我会在评论中问这个......)

编辑:第三个选项的参考版本:

class A_Config // stores common parts of A
{
public:
  A_Config(int a, int b) : m_a(a), m_b(b) {}
private:
  int m_a;
  int m_b;
};

class A // store parts changing for each instance and a reference to the common parts
{
public:
  A(int changing, A_Config& shared) : m_changing(changing), m_shared(shared) {}
private:
  int m_changing;
  A_Config& m_shared;
};

class B
{
public:
  B(int a, int b) : conf(a,b) {} // the common parts of A initialized 
                                 // only once when B is created

  void add_A(int changing) // add the changing parts when A is added
  {
    v.push_back( A(changing, conf) );
  }

private:
  A_Config conf;
  vector<A> v;
};
于 2013-03-17T18:24:06.873 回答
0

只是另一种方式:

std::vector <std::reference_wrapper<A>> vector_ref_A;

例子:

A a, b, c;

std::vector < std::reference_wrapper < A >> vector_ref_A = {a, b, c};

for (int i = 0; i < vector_ref_A.size(); ++i) {
    vector_ref_A[i].get().randomize();
}

for (int i = 0; i < vector_ref_A.size(); ++i) {
    vector_ref_A[i].get().print();
}
于 2013-03-17T17:37:20.970 回答