class B
{
public:
std::vector< std::vector<int> > vec;
void AtoB(const std::vector<int> &v)
{
vec.push_back(v);
}
}
上面的B类保存数据。
class A
{
public:
B* pSomeB;
void fnA()
{
std::vector<int> v;
for(int i = 0; i < 100; ++i)
{
v.push_back(rand());
}
pSomeB->AtoB(v);
}
void fnB()
{
pSomeB->push_back(std::vector<int>());
std::vector<int> &v(pSomeB->vec[pSomeB->vec.size()-1]);
for(int i = 0; i < 100; ++i)
{
v.push_back(rand());
}
}
}
A类有一个指向Struct B实例的指针.A :: fnA()和A :: fnB()以不同的方式实现它。
如果我们调用fnA,则向量在本地构造,然后由ref传递,然后复制到B :: vec中。如果我们调用fnB它会获取对插入到vecB中的向量的引用,所以我们超出了我们的范围,但是我们绕过了构造和复制的需要,并将其构造到目标中。
现在,班级设计标准从纯粹的理论水平中剔除。那么fnB应该不是更有效率吗?如果矢量变大,特别明显?我很惊讶地看到fnB导致了一个相当大的可执行文件。如果有人对此有一些了解,那将非常有用!
编辑由于下面的有用评论我遗憾地必须指出std :: move不是一个选项,因为其中一个要求是项目代码在C ++ 0x之前工作/ C ++ 11
答案 0 :(得分:0)
更正后,我将您的代码理解为fnB
,试图直接修改B的向量,而不是通过fnA
如果您质疑:这样做效率更高吗?
答案是:它并没有破坏封装(A
中的一个不应该看到B
内部的内容,因为它阻止了以后更改B
而不更改A
)
请注意,即使在fnB
你正在创建一个空矢量,你也会重新分配2D数组({I}猜测你想要的push_back
因此,您的代码目前正在进行fnA
中的102个分配(一个用于std :: vector,100个用于推回整数,一个用于拟合B向量中的向量)。这与fnB
中的计数相同。
为提高代码速度,您可以做的唯一(少数)事情是:
std::vector<std::unique_ptr<std::vector<int>>>
)。界面可能如下所示:
struct B
{
std::vector<std::unique_ptr<std::vector<int>>> array;
void append(std::vector<int> * v) { array.push_back(v); }
std::vector<int> & operator[] (const size_t index) { return *array[index]; }
};
struct A
{
B & b;
void fnA() {
// One allocation here
std::vector<int> * v = new std::vector<int>;
v->reserve(100); // Another allocation here
for(size_t i = 0; i < 100; v++) {
(*v)[i] = rand();
}
b.append(v); // Final allocation here => it's optimal
}
void exampleUse() { int i = b[0][2]; }
[...]
};