所以我有一个'大'班A
,另一个班B
,其中包含至少100个A
对象的向量。将B
类中的所有对象存储为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::b
和A::c
)由B
定义。类A
不是仅由B
使用的类,而是由用户或任何其他类使用的类。
所以基本上我要求一个方法,所以我不必为向量的每个元素设置A::b
和A::c
,但只需要一次。 A::a
对于我应该设置的每个元素都是不同的。
要找到我想要的原因:类A
在我的程序中是Sprite
类,而B
必须能够将精灵打印为tile并命名为TileMap
。 TileMap
中的向量因此可以在窗口上绘制很多Sprite
,但是对于所有这些图块(纹理图块大小,绘图图块大小,纹理文件等)我不想为每个瓷砖设置所有这些变量。我想创建一些可用于向量中的每个Sprite
的模板。这种方式不仅更容易,占用空间更少,而且更安全:我知道所有这些值都是完全相同的。
答案 0 :(得分: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
中的两个成员是一组。对于具有不同常量值的概念类,需要复制或重复该集合。
该理论是从不断变化的数据中分解出恒定的数据。
答案 1 :(得分:1)
如果变量b,c对于A的所有实例始终相同 - 在A中将它们设为静态。
如果变量b,c对于存储在B的一个实例中的A的实例集是相同的,则考虑将b,c放在B中。
如果变量b,c仅对某些A组相同,则考虑因子out b,c为它自己的“config”类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;
};
答案 2 :(得分: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();
}