управление указателем c ++ с локальными переменными - PullRequest
1 голос
/ 18 октября 2010

У меня есть метод, который создает некоторый Foo и добавляет его к вектору Foos.Foos отвечает за удаление своих баров во время уничтожения.Конструктор Foo берет указатель на столбцы и их размер.Когда функция возвращается, локальный Foo удаляется и разрушает его столбцы, однако я получаю обратно действительный объект Foo.

Как мне следует обрабатывать это более правильно?Должен ли я сделать так, чтобы Бары управлялись другим способом?Должен ли я иметь конструктор скопировать массив вместо этого?У меня потенциально будут сотни тысяч баров.

Я не пытался это скомпилировать, это всего лишь пример того, что происходит.

class Bar
{
    public:
        Bar(){}
        ~Bar(){}

        int a;
        int b;
        int c;
};

class Foo
{
    private:
        Bar * myBars;
        int size;

    public:
        Foo(Bar * myBars, int size)
        {
            this->myBars = myBars;
            this->size = size;
        }

        Bar * getBars()
        {
            return myBars;
        }

        int getSize()
        {
            return size;
        }

        ~Foo()
        {
            if(myBars != NULL)
            {
                if(size == 1)
                {
                    delete myBars;
                }
                else if(size > 1)
                {
                    delete [] myBars;
                }
            }
        }
};

void doIt(std::vector<Foo> & foos)
{
    Bar * myBars = new Bar[4];
    //Pretend we initialize the Bars...
    Foo foo(myBars);
    foos.push_back(foo);

    //local foo gets deleted
}

int main()
{
    std::vector<Foo> foos;
    doIt(foos);

    Bar * myBars = foos[0].getBars();
    int size = foos[0].getSize();

    //Do something with myBars

    return 0;
}

Ответы [ 3 ]

1 голос
/ 18 октября 2010

Почему бы не использовать std::vector для Bar с:

class Foo
{
    private:
        vector<Bar> myBars;

    public:
        Foo(const vector<Bar>& bars) : myBars(bars) {}

        vector<Bar>& getBars()
        {
            return myBars;
        }

        int getSize()
        {
            return myBars.size();
        }
};
0 голосов
/ 18 октября 2010

Вы не показываете конструктор копирования, и нет подходящего конструктора копирования по умолчанию.У вас также нет конструктора по умолчанию (без аргументов), который часто требуется контейнерам stl.

Когда вы помещаете Foo в вектор, он создает новый Foo в качестве копии.

В настоящее время вы, вероятно, удаляете указатель Bar дважды.

Следует избегать использования собственных массивов при использовании не POD-типов - Bar[4] не будет запускать конструктор в Bar для каждого объекта.Предпочитаю использовать Vector

0 голосов
/ 18 октября 2010

Как и в Bars, вы можете создавать объекты Foo также в куче, чтобы избежать разрушения в doIt functon. Если объект Foo выделяется динамически, он не будет уничтожен при возврате функции doIt ().

Вы можете очистить все объекты Foo и Bar в конце, как показано ниже (Рабочий код)

#include <vector>
using namespace std;
class Bar 
{ 
    public: 
        Bar(){} 
        ~Bar(){} 

        int a; 
        int b; 
        int c; 
}; 

class Foo 
{ 
    private: 
        Bar * myBars; 
        int size; 

    public: 
        Foo(Bar * myBars, int size) 
        { 
            this->myBars = myBars; 
            this->size = size; 
        } 

        Bar * getBars() 
        { 
            return myBars; 
        } 

        int getSize() 
        { 
            return size; 
        } 

        ~Foo() 
        { 
            if(myBars != NULL) 
            { 
                if(size == 1) 
                { 
                    delete myBars; 
                } 
                else if(size > 1) 
                { 
                    delete [] myBars; 
                } 
            } 
        } 
}; 

void doIt(std::vector<Foo *> & foos) 
{ 
    Bar * myBars = new Bar[4]; 
    //Pretend we initialize the Bars... 
    Foo *pFoo = new Foo(myBars, 4); 
    foos.push_back(pFoo); 
} 

int main() 
{ 
    std::vector<Foo *> foos; 
    doIt(foos); 

    Bar * myBars = foos[0]->getBars(); 
    int size = foos[0]->getSize(); 

    for(int i = 0;i < foos.size(); i++)
    {
        delete foos[i];
    }
    foos.clear();

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