I wrote a minimal example to test some behaviour. I tried to get std::dynamic_pointer_cast
to fail but encountered unexpected behaviour.
Here is the minimal example that I used:
//virtual_ipsum.h
class virtual_ipsum
{
public:
virtual_ipsum() { }
virtual ~virtual_ipsum() { }
};
//derived_lorem.h
#include "virtual_ipsum.h"
#include <iostream>
#define UUID_DERIVED_LOREM_RANDOM 2 //rolled it myself
class derived_lorem :
public virtual_ipsum
{
public:
derived_lorem(){ }
~derived_lorem(){ }
void o(){ std::cout << "lorem" << std::endl; };
};
//derived_adipiscing.h
#include "virtual_ipsum.h"
#include <iostream>
#define UUID_DERIVED_ADIPISCING_RANDOM 24 //rolled it myself
class derived_adipiscing :
public virtual_ipsum
{
public:
derived_adipiscing(){ }
~derived_adipiscing(){ }
void elit(){ std::cout << "donec" << std::endl; };
};
//server.h
#include <memory>
#include "virtual_ipsum.h"
//note that the header of the server can not contain the derived classes.
class server
{
public:
server() {}
~server() {}
std::shared_ptr<virtual_ipsum> getDerivedClassByUUID(int UUID);
};
//server.cpp
#include "server.h"
#include "derived_lorem.h"
std::shared_ptr<virtual_ipsum> server::getDerivedClassByUUID(int UUID)
{
// after careful examination of the UUID the
// server will send the correct derived class
return std::make_shared<derived_lorem>();
}
//client.h
#include <memory>
#include "server.h"
class client
{
private:
std::shared_ptr<server> s;
public:
client(std::shared_ptr<server> s) : s(s){}
~client(){}
void dolor();
void consectetur();
};
//client.cpp
#include "client.h"
#include "derived_lorem.h"
#include "derived_adipiscing.h"
#include <memory>
void client::dolor()
{
std::shared_ptr<virtual_ipsum> sit = s->getDerivedClassByUUID(UUID_DERIVED_LOREM_RANDOM);
std::shared_ptr<derived_lorem> amet = std::dynamic_pointer_cast<derived_lorem>(sit);
amet->o();
}
void client::consectetur()
{
std::shared_ptr<virtual_ipsum> felis = s->getDerivedClassByUUID(UUID_DERIVED_LOREM_RANDOM);
//everything should crash and burn
std::shared_ptr<derived_adipiscing> mauris = std::dynamic_pointer_cast<derived_adipiscing>(felis);
mauris->elit();
}
//main.cpp
#include <memory>
#include "server.h"
#include "client.h"
void main()
{
std::shared_ptr<server> s = std::make_shared<server>();
std::shared_ptr<client> c = std::make_shared<client>(s);
c->dolor();
c->consectetur();
}
对c->consectetur();
的调用应该失败,因为服务器返回了错误的派生类。相反,演员不仅是成功的,而且如果它是正确的类,也应该像它应该有的那样完成。
如何在投射期间在客户端检测到该问题?
答案 0 :(得分:1)
正如上述评论所指出的那样:
mauris->elit();
未定义。将客户端的实施更改为以下内容可解决此问题。
#include "client.h"
#include "derived_lorem.h"
#include "derived_adipiscing.h"
#include <memory>
void client::dolor()
{
std::shared_ptr<virtual_ipsum> sit = s->getDerivedClassByUUID(UUID_DERIVED_LOREM_RANDOM);
std::shared_ptr<derived_lorem> amet = std::dynamic_pointer_cast<derived_lorem>(sit);
if (amet)
{
amet->o();
}
else
{
std::cout << "amet is null" << std::endl;
}
}
void client::consectetur()
{
std::shared_ptr<virtual_ipsum> felis = s->getDerivedClassByUUID(UUID_DERIVED_LOREM_RANDOM);
//everything should crash and burn
std::shared_ptr<derived_adipiscing> mauris = std::dynamic_pointer_cast<derived_adipiscing>(felis);
if (mauris)
{
mauris->elit();
}
else
{
std::cout << "mauris is null" << std::endl;
}
}