Как скопировать объекты из векторного списка в другой векторный список? - PullRequest
0 голосов
/ 07 апреля 2011

Мне нравится копировать объект первого вектора во второй вектор, но когда я удаляю второй вектор, содержимое первого вектора не должно изменяться. Как я могу это сделать?

КОД:

typedef vector<CLog*> CLogData;

CLogData CMultiThreadedDlg::CopyLogData()
{
CLogData logdata;
for(size_t i = 0; i < m_pThreadInfo->GetLog().size()-1; ++i)
{
  CLog* plog = new CLog(*m_pThreadInfo->GetLog()[i]);
  logdata.push_back(plog);
}
return logdata;
}

DeleteData(logdata); 

void CMultiThreadedDlg::DeleteData(CLogData tLogData)
{
for(size_t i = 0; i < tLogData.size()-1; ++i)
{
    CLog* log = (CLog*)tLogData[i];
    delete log;
}

tLogData.clear();
 }

Проблема в моем коде заключается в том, что при удалении второго вектора первый вектор, а именно m_pThreadInfo-> getLog () содержимое также удаляется ..

Как это побороть?

EDIT:

     CLog::CLog()
     {
        m_threadname = new char[20];
     }
     CLog::~CLog()
     {
           delete[ ] m_threadname;
     }

Если я использую CLog в качестве параметра для векторного списка ... как я могу удалить это ...

Спасибо ...

Ответы [ 2 ]

4 голосов
/ 07 апреля 2011

О, чувак. В вашем коде есть серьезные проблемы.

Во-первых, у вас есть

class CLog
{
    char* m_threadname;

public:

    CLog()
    {
        m_threadname = new char[20];
    }

    ~CLog()
    {
        delete[ ] m_threadname;
    }
};

Это C ++, а 2011 год, пожалуйста, не делайте этого. И если вы это сделаете, не претендуйте на производительность в качестве причины. Вместо этого сделайте это:

class CLog
{
    std::string m_threadname;
};

См!

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

Вы можете использовать

typedef vector<shared_ptr<CLog>> CLogData;

Чтобы решить вашу проблему. Или предпочтительно

typedef vector<CLog> CLogData;

что еще лучше, пока не доказано обратное. Вы не дали вескую причину, почему это плохая идея.

Используй стек, это твой друг.

Изменить:

Кроме того, вам нужно привести свои рекомендации в порядок. В

void CMultiThreadedDlg::DeleteData(CLogData tLogData)
{
    for(size_t i = 0; i < tLogData.size()-1; ++i)
    {
        CLog* log = (CLog*)tLogData[i];
        delete log;
    }

    tLogData.clear();
}

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

2 голосов
/ 07 апреля 2011

Имея vector<CLog*>, программа просто становится излишне сложной. Я предлагаю вам использовать vector<CLog> вместо vector<CLog*>. С этой модификацией вам не нужно беспокоиться об явном удалении содержимого вектора. Вы можете просто использовать оператор присваивания, чтобы скопировать элементы одного вектора в другой.


На ваш комментарий по операции присваивания вектора -

#include <vector>
#include <iostream>

using namespace std;

int main()
{
    foo obj(10) ;

    vector<int> a(5), b(5) ;
    for( int i=0 ; i<5; ++i )
        a[i] = i ;

    b = a;  // Assignment 

    cout << b[2] << "\t" << a[2] << "\n";

    b[2] = 25;

    cout << b[2] << "\t" << a[2] << "\n";

    return 0 ;
}

Выход:

2 2
25 2

Смотрите, что модифицирующий вектор b не влияет на a. Таким образом, ваш комментарий не верен, что операция присваивания также изменяет другой вектор, если тип CLog.

Поскольку у класса есть элемент char*, операция присваивания не выполняет глубокого копирования. Вместо этого используйте std::string.

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