第三方库具有API Huge computeHuge()
。它返回对象本身,而不是引用/指针。我无法控制对象或API。
我有两节课:
class Bar {
Huge h;
Bar(Huge &huge): h(huge);
}
class Foo {
Bar b;
Foo() {
Huge h = computeHuge();
b = Bar(h);
}
[不幸的是,此设计(暂时)产生了一个大对象的两个副本:一个副本存在于Foo
构造函数中,而另一个副本存在于Bar
对象内部。一旦Foo
构造函数退出,就只有一个副本,但是我需要在构造函数内部加倍内存。由于h
可能是数百GB,因此很重要。
解决此问题的一种方法是使Foo
成为h
的所有者:
class Bar {
Huge &h;
Bar(Huge &huge): h(huge);
}
class Foo {
Bar b;
Huge h;
Foo() {
h = computeHuge();
b = Bar(h);
}
这确实消除了h
的两个副本,但在我的应用程序中并没有什么意义:Bar
是保存h
的正确选择。我如何:
computeHuge()
构造函数中调用Foo
Bar
保留h
的所有权h
的两个副本?如果Huge
是可移动的,则不会进行任何复制:
class Bar {
Huge h;
Bar(Huge huge): h(std::move(huge)) {} // move huge into its final place, h
};
class Foo {
Bar b;
Foo() {
Huge h = computeHuge();
b = Bar(std::move(h)); // move h into constructor argument
// h cannot be used here anymore
}
};
出于调试目的,这是一个(小)Huge
,不能复制,只能移动。每次尝试复制都是编译器错误:
struct Huge {
Huge() = default;
Huge(Huge&& other) { std::cout << "move "; }
Huge(const Huge& other) = delete;
Huge& operator=(Huge&& other) { std::cout << "move= "; return *this; }
Huge& operator=(const Huge& other) = delete;
};
这可能可行:在Bar中创建一个空对象,在Bar中添加一个函数以获取对其h的引用。
#include <iostream>
#include <vector>
class Huge
{
public:
std::vector<int> v;
};
class Bar
{
public:
Bar() : h() {};
Huge& GetHuge() { return h; };
Huge h;
};
class Foo
{
public:
Foo() : b()
{
Huge& h = b.GetHuge();
// computeHuge();
h.v.push_back(25);
};
int GetHugeOneInt(int ix)
{
Huge& h = b.GetHuge();
int i = h.v[ix];
return i;
};
Bar b;
};
int main()
{
Foo* myfoo = new Foo();
int i = myfoo->GetHugeOneInt(0);
std::cout << "Hello World!\n" << i;
std::getchar();
}