我正在尝试将地图数据发送到客户端,该客户端采用包含地图图块坐标的多个向量的形式。整个地图结构可以简化为这样的(不是实际的代码,但我也用这个重现了问题):
struct Tile {
sf::Vector3<int> coords;
};
struct Map {
Tile tiles[4];
};
然后,我使用这些运算符将此类对象添加到sf::Packet
:
sf::Packet& operator<<(sf::Packet& packet, sf::Vector3<int> vec) {
return packet << vec.x << vec.y << vec.z;
}
sf::Packet& operator>>(sf::Packet& packet, sf::Vector3<int> vec) {
return packet >> vec.x >> vec.y >> vec.z;
}
sf::Packet& operator<<(sf::Packet& packet, Tile test) {
return packet << test.coords;
}
sf::Packet& operator>>(sf::Packet& packet, Tile test) {
return packet >> test.coords;
}
sf::Packet& operator<<(sf::Packet& packet, Map test) {
for(int i = 0; i < 4; i++) {
packet << test.tiles[i];
}
return packet;
}
sf::Packet& operator>>(sf::Packet& packet, Map test) {
for(int i = 0; i < 4; i++) {
packet >> test.tiles[i];
}
return packet;
}
到此为止,不应该出现任何问题:必须将地图反序列化为4个图块,必须将其反序列化为sf::Vector3<int>
本身。
然后发送:
Tile test;
test.coords.x = 42;
test.coords.y = 34;
test.coords.z = 43;
Map test3;
test3.tiles[0] = test;
sf::Packet packet;
packet << test3;
sock.send(packet);
这段代码效果很好(我用GDB检查了packet
的内容,数据确实相同)。接收代码在服务器端也很有效:
sf::Packet packet;
sock.receive(packet);
Map test;
cout << "packet received" << endl;
检查数据包的内容(仍然使用GDB)提供与发送时相同的内容。 test
的内容是随机的(这是正常的,因为它还没有被初始化)。
将实际数据包数据反序列化为test
变量时会发生真正的问题:
if(packet >> test) {
cout << test.tiles[0].coords.x;
} else {
cout << "fail" << endl;
}
打印结果为0.反序列化表现良好(没有&#34;失败&#34;出现在控制台中),但数据不正确。使用GDB检查test
的内容会显示其数组为0的每个元素。这是GDB的输出:
(gdb) print test
$1 = {tiles = {{coords = {x = 0, y = 0, z = 0}}, {coords = {x = 0, y = 0, z = 0}}, {coords = {x = 0, y = 0, z = 0}}, {coords = {
x = 0, y = 0, z = 0}}}}
这可能是什么原因?我很确定我在这里做错了什么,但我真的无法理解。
提前感谢您的任何帮助:)
答案 0 :(得分:1)
好的,我终于明白了为什么这不起作用。 答案当然是非常愚蠢的,而且是典型的傻C ++初学者:D。
使用操作符函数而不通过引用传递对象没有一次机会工作(因为变量的内容将保留在操作符函数中而不会被更改)。
所以,改变这个:
sf::Packet& operator>>(sf::Packet& packet, Map test) {
for(int i = 0; i < 4; i++) {
packet >> test.tiles[i];
}
return packet;
}
到此:
sf::Packet& operator>>(sf::Packet& packet, Map& test) {
for(int i = 0; i < 4; i++) {
packet >> test.tiles[i];
}
return packet;
}
效果更好:)