2013-04-12 5 views
0

Я делаю приложение, которое запрашивает базу данных MySQL.Создание нескольких объектов класса с тем же именем? C++

Я хочу, чтобы результаты этого должны быть сохранены в карте (которая имеет соответствующую пару):

std::map<int, Car*> m_car; 
typedef std::pair<int, Car*> m_car_pair; 

Объект автомобиля состоит из 8 параметров, один из которых car_id так, во-первых я тяну идентификатор автомобиля и использовать его в качестве ключа, тогда я хочу сохранить весь объект автомобиля в качестве значения карты. (Я знаю, что это заставляет меня хранить car_id дважды, но на данный момент я не против этого).

Во всяком случае, вот мой код запроса:

void DatabaseController::getAll(QString query_string) 
{ 
    // Console log message 
    std::cout << "Querying Database" << std::endl; 

    /// Declare SQL query and pass function parameter 'query' 
    QSqlQuery query(query_string); 

    // execute the query 
    query.exec(); 

    int count = 0; 

    // While results are coming in 
    while(query.next()) 
    { 
     // Call car constructor passing all parameters 
     Car car(query.value(count).toInt(), query.value(count+1).toString(), query.value(count+2).toString(), query.value(count+3).toString(), 
      query.value(count+4).toInt(), query.value(count+5).toInt(), query.value(count+6).toInt(), query.value(count+7).toString()); 

     if (car.getcarID() != 0) 
     { 
      m_car_records.insert(m_car_pair(car.getcarID(), &car)); 
     } 
    } 

    std::cout << "Database query finished" << std::endl; 

После этого я сделал быструю тестовую функцию для итерации по карте и вытаскивать все (ключ карты) идентификатора и проверить они были разными (т.е. функция работала), и они были.

Но это была всего лишь проверка того, что мне нужно было, чтобы иметь возможность называть вспомогательные функции от автомобиля на автомобильных объектах, которые должны находиться на карте. Таким образом, я использовал ту же самую функцию быстрого теста, чтобы перебрать карты и cout << car.toString(); (простой в строчной функции в классе автомобилей):

void DatabaseController::test() 
{ 
    m_car_records_iterator = m_car_records.begin(); 

    for(unsigned int i = 0; i < m_car_records.size(); i++) 
    { 
     car *test = m_car_records_iterator->second; 
     std::cout << test->toString() << std::endl; 
     m_car_records_iterator++; 
    } 
} 

Это показал правильное количество результатов, однако все они были такими же, то есть автомобиль объект, который был добавлен к каждой записи в карте есть одни и те же (значения последней записи, найденной по запросу)

Мой вопрос ...

есть ли способ, что использование эта структура, которую я в настоящее время имею для моего запроса, могу создать и добавить эти классы obj ects на мою карту в цикле while, используя одно и то же имя для каждого из них, потому что, конечно, я не могу знать, сколько результатов возвращается и объявить объект класса для каждого из них, но поскольку оно стоит с использованием одного и того же имени, тот же самый каждый раз, фактически не заменяя значения ... по крайней мере, это то, что я думаю, происходит?

Любые советы или идеи будут приветствоваться (извините за длинный пост)

+0

Повторная вставка адреса локальной переменной стека 'car' на вашу карту, вероятно, не даст вам то, что вы хотите. Я бы начал там. – WhozCraig

ответ

2

Вы испытываете неопределенное поведение. Причина в том, что вы вставляете указатель на локальную переменную на карте.

В цикле getAll, когда цикл начинается с следующего элемента, переменная car больше не действительна.

Предлагаю вам посмотреть на std::shared_ptr для указателей.

+0

Cheers dude все работает сейчас – AngryDuck

+0

Оба ответа одинаково правы, но вы ответили сначала так плохо, согласитесь, спасибо всем, хотя – AngryDuck

2

Это ваш problem--

Car car(...); // ***Stack allocated 

if (car.getcarID() != 0) 
{ 
    m_car_records.insert(m_car_pair(car.getcarID(), &car)); 
} 
    //But the pointer is what's stored 

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

Car* car = new Car(...); 

, а затем, когда m_car больше не нужен, вам не нужно перебирать и delete его Car значения.

+0

Как правило, нельзя было бы помещать необработанные указатели в любые контейнеры 'std', такие как' vector', 'map' и т. д. В чем смысл? Поместите свои фактические объекты туда. –

+0

@Joker_vD Полиморфизм времени выполнения. 'shared_ptr' и т. п. - это еще один вариант, но не всегда необходимый, и преобразование base/производное в них немного сложнее. –

+1

ohhh cheers haha ​​довольно легко исправить все работающие сейчас (и в случае, если это похоже на реальную ошибку новобранец *, который уверен, что это * им новый для C++) приветствия для помощи людям – AngryDuck

Смежные вопросы