Проблема конструктора C ++, значения не установлены - PullRequest
2 голосов
/ 07 июня 2010

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

#pragma once
#include <irrlicht.h>
#include <vector>
#include <cassert>

using namespace irr;
using namespace core;
using namespace scene;

enum
{
    PLAYER = 0,
    NPC = 1,
    SOLDIER = 2,
    CHAINGUNNER = 3

};

class Model
{
    public:
        Model(void);
        Model(int id, std::vector<ISceneNode*> modelVec, int modType);
        ~Model(void);

        std::vector<int> path;
        std::vector<ISceneNode*> model;
        int endNode;
        int type;
        int animate;
        int health;
        u32 lastAnimation;

    private:
        int mId;
};

#include "Model.h"

Model::Model(void)
{
    //assert(false);
}

Model::Model(int id, std::vector<ISceneNode*> modelVec, int modType)
{
    path = std::vector<int>();
    model = modelVec;
    endNode = 0;
    type = modType;
    animate = 0;
    health = 100;
    lastAnimation = 0;
    mId = id;
}

Model::~Model(void)
{}

Я создаю модель с Моделью солдата (идентификатор, модель, СОЛДАТ) Все настроено правильно, кроме типа и здоровья. Я пробовал много разных вещей, но я не могу понять свою проблему. Я не уверен, но вызывается конструктор по умолчанию. Это не имеет смысла, потому что я не обращаюсь к этому конструктору.

Спасибо,

vector<ISceneNode*> model;
model.push_back(soldierBody);
model.push_back(soldierHead);
model.push_back(soldierWeapon);

cout << "Id of char: " << id << endl;

Model soldier(id, model, SOLDIER);
modelMap[id] = soldier;

Ответы [ 3 ]

2 голосов
/ 07 июня 2010

Это строки:

modelMap[id] = soldier;

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

Чтобы проверить, работает ли он, попробуйте:

Model soldier(id, model, SOLDIER);
std::cout << "TYPE(" << soldier.type << ")  HEALTH(" << soldier.health << ")" std::endl;

modelMap[id] = soldier;
std::cout << "TYPE(" << modelMap[id].type << "  HEALTH(" << modelMap[id].health << ")" std::endl;

Если ваш класс не предназначен для использования по умолчанию.
Тогда не используйте конструктор по умолчанию (это приведет только к проблемам).
Объявите конструктор по умолчанию в закрытой части класса (нет необходимости в теле).

Без конструктора по умолчанию вы не сможете использовать оператор [] на карте. Но вы можете обойти это, используя insert:

modelMap.insert(std::map<XX, Model>::value_type(id, soldier));
2 голосов
/ 07 июня 2010

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

modelMap[id] = Model(id, model, SOLDIER);

std::map::operator[] требует, чтобы отображаемый тип был конструируемым по умолчанию.Когда вы вызываете operator[] на карте, если с данным ключом нет сопоставленного значения, карта по умолчанию создает новый объект, сопоставляет его с данным ключом и возвращает ссылку на этот объект.

Вы можете обойти это, используя std::map::insert():

modelMap.insert(std::make_pair(id, Model(id, model, SOLDIER));
1 голос
/ 07 июня 2010

Вы делаете:

Model soldier(id, model, SOLDIER); //1
modelMap[id] = soldier;            //2

Что здесь происходит?
1. Новый объект создан с использованием предоставленного вами конструктора.
2. Так называемый так называемый конструктор копирования оператор копирования назначается для копирования soldier в modelMap[id]. Вы не определили свой собственный конструктор копирования оператор назначения копирования, поэтому компилятор создает для вас одно значение по умолчанию, в большинстве случаев это просто копирование побайтной байтовой всей структуры данных на новый адрес памяти , Однако у вас есть вектор указателей в вашем классе, поэтому компилятор должен вызывать конструктор копирования вектора ... И я не знаю (возможно, кто-то с большим опытом точно знал бы, что происходит сейчас), каков результат copy- конструктор, я не знаю, четко ли стандарт определяет «конструктор копирования по умолчанию».

Так что вполне возможно, что вся структура скопирована в modelMap[], но с некоторыми случайными данными.

Если вы создаете конструктор копирования (его объявление в вашем случае будет выглядеть примерно так: Model::Model(const Model& myModel);, конструктор копирования всегда будет ссылаться на объект своего типа в качестве аргумента) Если вы переопределите назначение копирования оператор (лучше всего, если вы делаете обе вещи), вы можете контролировать все, что делается при копировании вашего объекта в другую переменную / объект.

Скачать, например. Брюса Экеля * Думая на C ++, V. 1 [1], или ищите где-нибудь в сети, как это сделать (возможно, это будет хорошо, не читал всю статью, http://www.learncpp.com/cpp-tutorial/911-the-copy-constructor-and-overloading-the-assignment-operator/).

[1] Доступно для скачивания на его сайте mindview.net. Как новый пользователь, я могу вставить только одну ссылку, поэтому не могу связать ее здесь самостоятельно: P.

...