Memory management and cleanup with inheritance:
Objects allocated with new must be cleaned up by calling delete. In this case the beverage object is never cleaned up. In modern (and not so modern) C++ we should use a std::unique_ptr instead of doing manual memory management.
When we call member functions on a pointer to the base-class (CaffeinatedBeverage), ...
The code is not bad, but I see some things that may help you improve it.
Check your spelling
There are some typos and peculiar capitalization in the strings displayed for the user. For instance "gut" should probably be "guys," "InValid" should be "Invalid" and "Direction Hit" should be "direct hit."...
An important point of the PIMPL is that it helps you hide details that you do not want to leak out to the public.
This means your header #include list is not expected to have more than the bare minimum and at times even no #include at all (although this last case is really rare).
Any class, struct, etc. used in your header file has to be declared in some way....
If you just started learning C++, I suggest reading through (and bookmarking) the C++ Core Guidelines. One example that pops out, from your opening remarks, is C.149, R.11, and P.9.
That is, rather than being puzzled as to where to put the delete statements due to exception handling, you should not be writing explicit calls to delete in your code.
I agree with everything Toby Speight wrote. I'd like to add:
Name things according to what they represent
You have this line of code:
tcp::resolver::iterator iterator = resolver.resolve(query);
But while iterator is indeed an iterator, that's not what is important about this variable. What really is important is that it is the result of the DNS query. So I ...
No need for a constructor if it does nothing.
if (telnet != nullptr)
The test here is pointless, since delete works fine with a null argument. We can improve on this by making telnet a smart pointer (probably std::unique_ptr<TelnetClient>), so that a default ...
Since we specify a value constructor, the compiler won't generate the default constructor. So we don't need to declare it private to prevent its use.
The move operators can declared = default:
X(X&& moveFrom) = default;
X& operator=(X&& moveFrom) = default;
You actually appear to have two copy assignment operators instead ...
The code is well formatted and also reasonably well implemented, lacking only a few security overhauls such as memory leaks and optimizations also completing the pending implementations of existing concepts in unique_ptr
Is it well-formed?
Yes, have good formatting
i.e. does it follow common C++ standard and patterns (for example,
should private ...
The declaration for the class PacketProc should be indented, right now the code is hard to read.
class Session : public std::enable_shared_from_this<Session>
void SetOnMsgProc(const message_handler&& on_msg_func)
this->inner_on_msg_func = on_msg_func;