Пожалуйста, рассмотрите следующий (простой) код. Странное (?) Поведение в main()
рутина и подробно ниже.
Packet.h
#include <string>
class Packet {
public:
Packet(int iParam, std::string sParam);
~Packet();
void setInt(int iParam);
void setString(std::string sParam);
private:
int iProperty_;
std::string sProperty_;
};
Packet.cpp
#include "Packet.h"using std::string;
Packet::Packet(int iParam, string sParam) : iProperty_(iParam),
sProperty_(sParam) {}
Packet::~Packet() {}
void Packet::setInt(int iParam) {
iProperty_ = iParam;
}
void Packet::setString(std::string sParam) {
sProperty_ = sParam;
}
PacketController.h
#include <string>
class PacketController {
public:
PacketController();
~PacketController();
PacketController & andSetInt(int iParam);
PacketController & andSetString(std::string sParam);
private:
Packet packet_;
};
PacketController.cpp
#include "PacketController.h"using std::string;
PacketController::PacketController() : packet_(0, "") {}
PacketController::~PacketController() {}
PacketController & PacketController::andSetInt(int iParam) {
packet_.setInt(iParam);
return *this;
}
PacketController & PacketController::andSetString(string sParam) {
packet_.setString(sParam);
return *this;
}
главный()
int main() {
PacketController& ctrlRef = PacketController()
.andSetString("hello world")
.andSetInt(19);
PacketController ctrlVal = PacketController()
.andSetString("hello world")
.andSetInt(19);
PacketController& ctrlRef2 = PacketController();
ctrlRef2.andSetString("hello world")
.andSetInt(19);
return 0;
}
Если исполнение приостановлено на линии return 0;
из main()
тогда следующие значения видны на внутренней packet_
объекты:
ctrlRef - packet_:
iProperty_: 19
sProperty_: ""
ctrlVal - packet_:
iProperty_: 19
sProperty_: "hello world"
ctrlRef2 - packet_:
iProperty_: 19
sProperty_: "hello world"
Так почему же sProperty_
пустой на packet_
объект в ctrlRef
? Это как-то связано с тем, что ссылка инициализируется при инициализации PacketController
объект? Но тогда почему iProperty_
на packet_
объект ctrlRef
правильно установлен на 19
?
PacketController& ctrlRef = PacketController()
.andSetString("hello world")
.andSetInt(19);
ctrlRef
является ссылкой на временное устройство, срок жизни которого закончился в конце оценки полного выражения (прямо в ;
). То же самое можно сказать и о ctrlRef2
,
Использование приводит к неопределенное поведение.
С другой стороны, ctrlVal
значение инициализируется из временного Использование это нормально.
Других решений пока нет …