Избежать освобождения из-за переменной области? - PullRequest
0 голосов
/ 21 января 2019

Мне нужно добиться следующего:

  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.

Спасибо за вашу помощь.

РЕДАКТИРОВАТЬ: код с unique_ptr , все еще с тем же выводом?

Code1 , работает, но выделяется дважды vA, vB, vC, vD, code2 , не работает, но без дополнительного выделения.

1 Ответ

0 голосов
/ 21 января 2019

Если вы накладываете искусственные ограничения типа «без использования нового», вы должны хорошо понимать C ++.Похоже, вы знакомы с некоторыми основами.

Давайте начнем с первой части вашей цели: «Создать переменную в любом месте кода без использования new;».В C ++ переменные не создаются с new.Они созданы декларациями.new создает неназванные объекты и возвращает указатель на этот объект.

У вас есть вторая цель, которая облегчает жизнь.«Убедитесь, что он никогда не будет освобожден».В C ++ вы должны выбрать, как хранить указатель, возвращаемый new.Храните его в обычном (не интеллектуальном) указателе и не вызывайте delete, и вы будете уверены, что объект никогда не освобождается.

Как вы правильно поняли, в C ++ не все объектысозданы new.Объявления обычных переменных внутри функций создают локальные переменные, чьи объекты имеют время жизни, которое заканчивается, когда функция возвращается.Это неизбежно.

Вы можете иметь переменные внутри функций, которые выживают после возврата этих функций;они объявлены с static.Их время жизни до конца программы.Но, похоже, они тебе не помогут;вы получаете одну и ту же переменную каждый раз, когда вызывается функция.И ваше дерево, очевидно, имеет более одного узла.Это действительно не удивительно.Как и глобальные объекты, память для static объектов может быть выделена при запуске программы.Оба имеют так называемую статическую продолжительность хранения и занимают ограниченный объем памяти.

Итак, в заключение вы не можете избежать new.Вы можете скрыть это, хотя.И вы, вероятно, должны.Используете ли вы std::vector<A> или std::list<A>, каждый объект A в контейнере в конечном итоге создается с помощью new.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...