#include <iostream>
#include <string>
#include <memory>
#include <ctime>
#include <thread>
#include <chrono>
class AbstractUser
{
std::string myNick;
public:
std::string getMyNick() const {return myNick;}
void setMyNick (std::string_view myNick) {this->myNick = myNick;}
virtual std::string sayMyEntity()const=0;
virtual ~AbstractUser()=default;
};
class Human:public AbstractUser
{
public:
std::string sayMyEntity()const override
{
return "I'm a HUMAN "+getMyNick();
}
};
class Computer :public AbstractUser
{
public:
std::string sayMyEntity()const override
{
return "I'm a Computer "+getMyNick();
}
};
class Dispatcher
{
std::unique_ptr<AbstractUser> think;
public:
Dispatcher()
{
uint64_t i = std::rand();
if (i% 2 ==0)
{
//think = new Human;
think = std::make_unique<Human>();
}
else
{
//think = new Computer;
think = std::make_unique<Computer>();
}
think->setMyNick(std::to_string(i)+"");
}
public:
std::string describeMe()const
{
if(!think)return {};
return think->sayMyEntity();
}
//тут осторожно! - возвращается голый указатель.
//Память по нему нельзя освобождать снаружи!
//(если требуется другая логика, нужно переделать метод по ситуации)
const AbstractUser* getThink()const
{
return think.get();
}
};
int main()
{
std::srand(std::time({}));
for (int i=0; i<100; i++)
{
std::this_thread::sleep_for(std::chrono::milliseconds(50));
Dispatcher disp;
std::cout<<disp.describeMe()<<", ";
if(auto* think=disp.getThink())
{
std::cout<<think->getMyNick();
}
else
{
std::cout<<"nullptr";
}
std::cout<<'\n';
}
}