避免由于可变范围而取消分配?

时间:2019-01-21 09:51:14

标签: c++ object memory-management

我需要实现以下目标:

  1. 在代码中的任何位置创建变量,而无需使用new;
  2. 任何时候,请为该变量保留一个处理程序,并确保它永远不会被释放;

目标是创建一棵树,您可以在其中添加节点,而这只需要增加一个指针即可。

问题是我不知道如何做第2点,因为如果不使用new则在离开函数时会释放变量。

A类示例:

#include <vector>
#include <iostream>

class A
{
    int value;
    std::vector<const A*> sub_blocks;
public:
    A(int v)
    {
        value = v;
        sub_blocks = std::vector<const A*>();
    };

    A(std::vector<const A*> subs)
    {
        sub_blocks = subs;
    };
    A merge(const A & b, const A & c, const A & d);

    friend std::ostream & operator<<(std::ostream & o, const A & si) {
        if (si.sub_blocks.empty()) { return o << si.value; }
        for (auto it = si.sub_blocks.begin(); it != si.sub_blocks.end(); it++)
        {
            o << (*it)->value;
        }
        return o;
    }
};

A A::merge(const A & b, const A & c, const A & d)
{
    std::vector<const A*> toReturn;
    toReturn.push_back(this);
    toReturn.push_back(&b);
    toReturn.push_back(&c);
    toReturn.push_back(&d);
    return A(toReturn);
}

A func1()
{
    A vA = A(3);
    A vB = A(4);
    A vC = A(1);
    A vD = A(5);

    A vE = vA.merge(vB, vC, vD);
    std::cout << vE << std::endl;
    return vE;
}

int main()
{
    A vOutside = func1();
    std::cout << vOutside << std::endl;
};

输出为3415????。我想要3415 3415

感谢您的帮助。

EDIT:代码with unique_ptr仍然具有相同的输出?

Code1,可以工作,但是分配了两次vA, vB, vC, vDcode2,但是没有工作,但是没有额外的分配。

1 个答案:

答案 0 :(得分:2)

如果强加诸如“不使用new”之类的人为约束,那么您应该对C ++有很好的理解。看来您是在一些基础知识上绊倒了。

让我们从目标的第一部分开始:“在代码中的任何位置创建变量,而无需使用new;”。在C ++中,变量不是用new创建的。它们是通过声明创建的。 new创建未命名的对象,并返回指向该对象的指针。

您还有第二个目标,可以使生活更轻松。 “确保它永远不会被释放”。在C ++中,您应该选择如何存储new返回的指针。将其存储在常规(非智能)指针中,不要调用delete,您可以确定该对象永远不会释放。

您正确地发现,在C ++中,并非所有对象都由new创建。函数内部的普通变量声明创建局部变量,其对象的生存期在函数返回时结束。那是不可避免的。

可以在函数内部具有变量,这些变量在返回这些函数后仍然有效;这些用static声明。它们的生命周期到程序结束。但是看起来他们不会帮助您。每次调用该函数时,都会得到相同的变量。而且您的树显然具有多个节点。这真的不足为奇。像全局对象一样,static对象的内存可以在程序启动时分配。两者都有所谓的“ 静态存储持续时间”,并且占用的存储空间有限。

因此,总而言之,您无法避免使用new。您可以将其隐藏。而且您可能应该。无论使用std::vector<A>还是std::list<A>,容器中的每个A对象最终都是由new创建的。