Деструктор обратился к объекту при добавлении его к станд.:: список

Думаю, я понял это только после небольшой помощи @Parfait (спасибо, @Parfait!). В случае, если кто-то еще искал ответ, это сработало для меня, но я бы приветствовал любые другие ответы:

lapply(1:numrows, function(i)  getDetails(cars[i,]))

и мне пришлось изменить мою функцию, чтобы она возвращала вектор вместо списка: [ 113]

getDetails<-function(parameters){
   valueA<-parameters[1]+45
   valueB<-parameters[1]+10
   c(valueA, valueB)
}
9
задан Bill the Lizard 16 August 2010 в 13:31
поделиться

5 ответов

Когда Вы push_back () Ваш объект Foo, объект копируется во внутренние структуры данных списка, поэтому Dtor и Ctor другого экземпляра называют.

Все стандартные типы контейнера STL в C++ берут свои объекты значением, поэтому копируя их по мере необходимости. Например, каждый раз, когда вектор должен вырасти, возможно, что все значения в векторе копируются.

Возможно, Вы хотите сохранить указатели вместо объектов в списке. Путем выполнения этого только указатели копируются вместо объекта. Но, таким образом, необходимо удостовериться, что удалили объекты, после того как Вы сделаны:

for (std::list<Foo*>::iterator it = list.begin(); it != list.end(); ++it) {
    delete *it;
}
list.clear();

С другой стороны, можно попытаться использовать некоторый класс 'интеллектуального указателя', например, из библиотек Boost.

14
ответ дан 4 December 2019 в 10:05
поделиться

Вы создаете временного Foo здесь:

li.push_back( Foo() )

push_back копирует того Foo в свои внутренние структуры данных. Временный Foo уничтожается после того, как push_back был выполнен, который назовет деструктор.

Вам будет нужен надлежащий конструктор копии, который увеличивает некоторый подсчет ссылок на участниках класса, которых Вы не хотите уничтожать рано - или делать его частным для принуждения себя на решении для указателя.

4
ответ дан 4 December 2019 в 10:05
поделиться

Что на самом деле происходит, вот то, что Вы храните копию переданного объекта в списке, потому что Вы отправляете его значением вместо ссылкой. Таким образом, первый dtor, который называют, на самом деле называют на объекте, который Вы передаете push_back методу, но новый экземпляр был создан к тому времени, и он теперь хранится в списке.

Если Вы не хотите, чтобы копия объекта Foo была создана, указатели хранилища на объекты Foo в списке вместо самих объектов. Конечно, при выполнении его необходимо будет правильно освободить память на разрушении списка.

1
ответ дан 4 December 2019 в 10:05
поделиться

Используйте этот объект понять:

class Foo
{
public:
    Foo(int x): m_x(x)
    { 
    std::cout << "Constructed Object: " << m_x << ")\n";
    }
    Foo(Foo const& c): m_x(c.m_x+100)
    {
    std::cout << "Copied Object: " << m_x << ")\n";
    }
    ~Foo()
    {  
    std::cout << "Destroyed Object: " << m_x << ")\n";
    }
};

Первое основное

std::list<Foo*> li;
li.push_back(Foo(1));

Здесь мы создаем временный объект Foo и называем push_back (). Временный объект копируется в список и функциональные возвраты. На завершении этого оператора временный объект затем уничтожается (через деструктор). Когда список будет уничтожен, он также уничтожит весь obejcts, который он содержит (Foo является объектом с деструктором, таким образом, разрушение включает вызов деструктора).

Таким образом, необходимо видеть что-то как это:

Constructed Object: 1
Constructed Object: 101
DestroyedObject: 1
DestroyedObject: 101

Во втором примере Вы имеете:

std::list<Foo*> li;
li.push_back(new Foo(1));

Здесь Вы динамично создаете объект на "куче". Затем назовите push_back (). Здесь указатель копируется в список (указатель не имеет никакого конструктора/деструктора), таким образом, ничего иного не происходит. Список теперь содержит указатель на объект на "куче". Когда функциональные возвраты ничто иное не сделано. Когда список уничтожается, он уничтожает (обратите внимание, что тонкое различие betweens уничтожает и удаляет), объект, который он содержит (указатель), но указатель не имеет никакого деструктора, таким образом, ничего не происходит никто, что Вы пропустите память.

Таким образом, необходимо видеть что-то как это:

Constructed Object: 1
2
ответ дан 4 December 2019 в 10:05
поделиться

Создание списка, содержащего указатели вместо экземпляров, решает проблему с называемым деструктором. Но я все еще хочу понять, почему это происходит.

#include <iostream>
#include <list>

class Foo
{
public:
    Foo()
    { 
        int breakpoint = 0;
    }
    ~Foo()
    { 
        int breakpoint = 0;
    }
};

int main()
{
    std::list<Foo*> li;
    li.push_back(new Foo());
}
0
ответ дан 4 December 2019 в 10:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: