Как скопировать объекты из векторного списка в другой векторный список?

#c #stl #vector

#c #stl #векторный

Вопрос:

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

код:

 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()..

Как это преодолеть?

Редактировать:

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

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

Спасибо…

Комментарии:

1. Это реальный код? потому что он не компилируется. Кстати, как реализован конструктор копирования CLog класса? выполняется глубокое копирование?

2. это реальное приложение .. я просто вставил сюда свою функциональность…

3. Я полагаю, вы имели в виду typedef vector<CLog*> CLogData; , не vector<CLog*> CLogData;

Ответ №1:

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

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

 class CLog
{
    char* m_threadname;

public:

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

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

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

 class CLog
{
    std::string m_threadname;
};
  

Смотрите!

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

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

 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() отредактирована, а не оригинал. Может быть опасно, если он зависает, и вы думаете, что у него есть действительные указатели, которых на самом деле нет.

Комментарии:

1. Возможно ли сохранить одну запись lakh в vector<CLog> ?

2. @karthik: Извините, я не могу вас понять. Не могли бы вы, пожалуйста, пояснить?

Ответ №2:

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


По вашему комментарию об операции присваивания вектора —

 #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 вместо этого.

Комментарии:

1. Извините, мне приходится использовать во многих классах и многих files…so мне нужно использовать CLog * и, более того, если мы используем CLog и используем оператор присваивания, то изменения в одном векторе влияют на содержимое другого вектора..

2. AFAIK, доступ ко многим файлам не имеет ничего общего с CLog* ? Операция присваивания ( = ) копирует содержимое одного вектора в другой. Таким образом, изменение одного вектора не влияет на другой вектор. Попробуйте очень простую программу и посмотрите ее.

3. Внутри класса CLog я использую две переменные char *, а именно threadname и message … как я могу это удалить?

4. В основном избегайте использования необработанных указателей. Используйте std::string вместо этого.

5. Попробуйте дать решение для CLog * … для последнего шанса я воспользуюсь вашей логикой…. Справка по проблеме CLog *