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

Dispose of old variable used to construct useful value

本文关键字:变量 有用 用于 处理      更新时间:2023-10-16

假设以下两个类:

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在逻辑上是非常紧凑的,我想避免将其拆分为函数,因为在这种情况下几乎没有任何收获。

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

你可以将默认构造的对象分配给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实例。

很大程度上,这取决于您在程序中创建的类。AB都必须具有通用协议(或其他类的子协议(,以及暗示该协议的公共存储(例如某些自定义structvector(。如果是这种情况,则负责的类可以具有资源委派的功能(如set_owner(,另一个类可以利用该函数。模式在很大程度上(或完全(取决于您拥有的类/资源/模式。

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

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