У меня есть одноэлементный класс, содержащий вектор с данными. Моя проблема в том, что я хочу добавить данные к этому вектору, используя стандартный метод push_back(). У меня есть объект, который я хочу сохранить в этом векторе, но это локальный объект (созданный в методе другого класса). Очевидно, что в конце этого метода локальная переменная будет удалена, что отлично, потому что я делаю push_back() этих данных для вектора.
Теперь это прекрасно работает, поскольку метод не заканчивается. После этого данные исчезли. Это кажется странным, потому что push_back() должен использовать конструктор копирования правильно? Теперь я попытался добавить локальную переменную в вектор по ссылке, по значению, как указатель и с конструктором перемещения в С++ 11, но все эти вещи не работают.
Итак, это настройка проблемы по классу:
Короче говоря, я хочу, чтобы объект, созданный в методе ClassA, был доступен после этого метода, но в векторе из класса ConnectionManager.
EDIT: Здесь типX, о котором я говорю:
struct Connection
{
SOCKET socket;
PlayerData* pPlayerData;
};
socket - это ваша обычная переменная SOCKET winsock, а PlayerData * - это настраиваемый объект, созданный с помощью Google ProtocolBuffer.
ДАЛЬНЕЙШЕЕ ИЗМЕНЕНИЕ:
Вот как я создаю данные:
Predefined::Connection connTemp;
connTemp.socket = 0;
connTemp.pPlayerData = data;
MultiplayerData::GetInstance()->AddPlayerToGame(connTemp);
connTemp.pPlayerData является, чтобы ответить на вопрос, локально созданная переменная, но она была создана как указатель.
Если проблема заключается в том, что вы создаете данные PlayerData
и ожидаете, что все эти же данные будут доступны после выхода функции, похоже, что вы должны использовать тип, например std::shared_ptr<PlayerData>
а не голый PlayerData*
.
#include <vector>
#include <memory>
//..
class PlayerData
{
int x, y, z;
public:
PlayerData(int a1, int a2, int a3) : x(a1), y(a2), z(a3) {}
};
typedef std::shared_ptr<PlayerData> PlayerDataPtr;
struct Connection
{
SOCKET socket;
PlayerDataPtr pPlayerData;
};
typedef std::vector<Connection> ConnectionVector;
void foo()
{
auto data = std::make_shared<PlayerData>(1, 2, 3); // create data dynamically
//...
Connection connTemp;
connTemp.socket = 0;
connTemp.pPlayerData = data;
MultiplayerData::GetInstance()->AddPlayerToGame(connTemp); // this does the push_back
//...
}
Поскольку pPlayerData
теперь является shared_ptr
, те копии, которые vector
генерирует, просто увеличивают количество ссылок, и, наоборот, когда эти копии уничтожаются, счетчик ссылок уменьшается. Когда счетчик ссылок достигает 0, data
действительно будут удалены.
Если вы не вызвали reset
на общий указатель, это более или менее, ваша гарантия того, что data
, созданные вами до push_back
будут существовать, пока эта запись в векторе не будет удалена.
Кроме того, я отредактировал этот пример, чтобы показать более простой класс PlayerData
. Обратите внимание, как используется make_shared
.
auto data = std::make_shared<PlayerData>(message.add_playerdata());
В нем говорится: 'PlayerData::PlayerData(const PlayerData &)' : cannot convert parameter 1 from 'PlayerData *' to 'const PlayerData &'
message.add_playerdata()
. Во-вторых, параметры make_shared
- это параметры, которые вам нужны для создания PlayerData
. Итак, вы говорите, что для создания PlayerData
вам нужно передать указатель на PlayerData
? Это звучит странно, и, возможно, причина, по которой вы теряете данные. Посмотрите на мой отредактированный код выше.
Соединение Struct действительно будет скопировано в вектор, поэтому вам не нужно беспокоиться о конце его жизни. Однако pPlayerData нужно указывать на память, выделенную новым и принадлежащую кому-то.
connTemp.pPlayerData = data;
Откуда берутся "данные" - генерируются локально? В какой-то момент "данные" должны быть выделены "новым".
Если "данные" уникальны, рассмотрите возможность использования auto_ptr или unique_ptr для типа члена pPlayerData. C++ не автоматически управляет стандартными указателями. Если они не уникальны, используйте shared_ptr или intrusive_ptr - можно начинать с совместного использования и дооснащения интрузивных позже.
typeX
?