处理用于构造有用值的旧变量

时间:2014-11-08 15:05:31

标签: c++ destroy temporary

假设以下两个类:

struct A {
    A()  {}
};

struct B {
    B(const A& a) {}
};

我多次碰巧遇到一种情况,我必须创建一个类的临时实例,以便构建我需要使用的东西的实例。类似的东西:

A a;
// Do very complex computations using a;
B b(a);
// use b, a is not needed anymore.
return make_result(b);

我的问题是,有时我的计算后a所拥有的资源可能很大,而我实例化b之后我想释放它们。同时,整个过程a -> b -> result在逻辑上是一个非常紧凑的事情,我想避免将其分解为函数,因为在这种情况下会有pretty much nothing to gain

C ++中有哪些可用的解决方案来解决这类问题?

2 个答案:

答案 0 :(得分:1)

您可以将默认构造的对象分配给A,假设A的赋值运算符正确释放"资源":

A a;
// Do very complex computations using a;
B b(a);
a = {};
// use b, a is not needed anymore.
return make_result(b);

您可以更改B按值A并将构建的A实例移至B

struct A {
    A()  {}
};

struct B {
    B(A a) {}
};
// ...
A a;
// Do very complex computations using a;
B b(std::move(a));
// use b, a is not needed anymore.
return make_result(b);

具有很好的优势,B的构造函数可以"窃取"来自A对象的资源。

您可以使用lambda构建A并将其传递给B

B b([&]{
    A a;
    // Do very complex computations using a;
    return a;
}());
// use b, a is not needed anymore.
return make_result(b);

您可以使用lambda 构建A使B按值获取:

struct A {
    A()  {}
};

struct B {
    B(A a) {}
};
// ...
B b([&]{
    A a;
    // Do very complex computations using a;
    return a;
}());
// use b, a is not needed anymore.
return make_result(b);

允许BA窃取内容,但不会留下僵尸A实例。

答案 1 :(得分:0)

很大程度上取决于您在程序中制作的课程。 AB都必须具有通用协议(或其他类的子协议),以及暗示该协议的公共存储(例如某个自定义vector的{​​{1}} )。如果是这种情况,那么负有责任的类可以具有 resource-delegation 的功能(如struct),这是另一个类可以使用的。该模式在很大程度上(或完全)取决于您拥有的类/资源/模式。

如果存在某些通用协议,则可以适当地更改一个或两个(或多个)类。

如果类相似(例如涉及继承或嵌套类),则可以使用返回值优化,Name-RVO或set_owner构造。