Finding a good modelisation for some objects - c++

For a school project, I need to send and receive some data named as TLV through the network.
In fact, because a TLV can be small, the application send a meta-TLV that groups several TLV in a packet.
My problem is the following : what are the classes that I need to create to modelise properly the TLV ?
I don't know if I need to mention all the TLV possible but what I know is the following :
-Every TLV has a field type that identify the semantic of the TLV
-Every TLV but one has a field length. However for five TLV, this sized is fixed
-Two TLV has exactly the same field : type, length=0
-Three TLV has exactly the same field : type, length=8 and id. Just the type change (and their name)
The other are quite different.
My first idea was to use a mother class TLV that has a enum to store all the different TLV allowed like this :
//enum class to avoid conflicts
enum class TlvType {
Pad1,
PadN,
Bad,
No,
PeersReq,
Peers,
Data,
IHave,
IDontHave,
INeed,
// Unknown,
};
class Tlv {
private:
virtual void to_stream(std::ostream& output) const = 0;
protected:
uint8_t length_;
public:
virtual TlvType type() const = 0;
/*Solution find here : http://stackoverflow.com/questions/2059058/c-abstract-class-operator-overloading-and-interface-enforcement-question*/
friend std::ostream &operator<<(std::ostream& output, const Tlv& tlv) {
tlv.to_stream(output);
return output;
}
//TO DO : do we really need that this method is virtual ?
virtual uint8_t length() const;
Tlv();
virtual ~Tlv() {}
};
class PadN : public Tlv {
private:
void to_stream(std::ostream& output) const;
static constexpr TlvType code() {return TlvType::PadN;}
public:
TlvType type() const;
PadN();
PadN(uint8_t zero_bytes);
void set_length(uint8_t length);
};
The problem is that this codes somehow an algebraic type, that introduces a lot of redundant code. For example, I need to define for each tlv the method TlvType type() const . Since some Tlv has a fixed size, I only want a setter for the ones that can change their size.
Moreover each Tlv will be then formated in a format ready to send to the network. This, looks like a lot to serialization. However, I think that serialization is overkill for this project. Besides, since it's a network project, each student use his own language. And the only thing that we know is the format of a tlv that needs to be sent through the network.
Because my code is quite redundant I think that my modelisation is wrong for the TLV. And I'm doubting about using a class for each TLV. Indeed, probably the user won't change his TLV once he created it. He just wants to send it. And there is the same problem for the other way: I need to receive TLV. So I'm not sure how should I do.

Related

How can I access a private (non-static) method in C++?

Currently I am working on a project where I want to control a model train for a nice showcase.
I have multiple locomotives which all have a unique address (just think of it as a UUID). Some locomotives have a headlight, some of them have a flashing light, some have both and some of them have none.
My base class is this:
class GenericLocomotive : public Nameable, public Describable {
private:
uint16_t address;
public:
GenericLocomotive(const char* name, const char* description, uint16_t address);
void setFunction(uint8_t command, bool val);
Now I want to have a different class which provides the functionality to enable and disable the headlight:
class HasHeadLight {
public:
void activateHeadlight();
void deactivateHeadlight();
}
My goal is to have a specific class for every locomotive (with different functionality) which looks something like this:
class <SpecificLocomotive> : public GenericLocomotive, public HasHeadlight, public HasFlashlight,... {
...
}
The problem is, that I must have access to the private field 'address' of my GenericLocomotive class and I also have to call the function setFunction(...) from my HasHeadlight class.
I am quite new to C++ and just found out about the concept of friend classes and methods, but I can not quite get it to work, because even with the declaration of the method setFunction(...) as a friend, I can not just call something like
this->setFunction(HEADLIGHT_COMMAND, true);
from my HasHeadlight-class, because the function is not declared in 'this'.
How can I access the method from my other class? Is this friend thing even needed or is there a completely different way to structure my C++ program?
You have misunderstood how class inheritance works:
Inheritance establishes an is-a relationship between a parent and a child. The is-a relationship is typically stated as as a specialization relationship, i.e., child is-a parent.
There are many ways you can tackle what you want to achieve here, but this is not it. You're on the right track as far as treating the different train components as separate objects, and one way to achieve that would be to instead make each component a member of the specialized locomotive:
class HeadLight {
public:
void activateHeadlight();
void deactivateHeadlight();
}
class SpecialLocomotive : public GenericLocomotive {
HeadLight mHeadlight;
Flashlight mFlashlight;
public:
SpecialLocomotive(const char* name, const char* description, uint16_t address)
: GenericLocomotive(name, description, address) {
setFunction(HEADLIGHT_COMMAND, true);
}
void toggleLight(bool on) {
if (on) {
mHeadlight.activateHeadlight();
} else {
mHeadlight.void deactivateHeadlight();
}
}
/* so on and so forth /*
}
There's not enough details to go further with it. If you need to call setFunction from within Headlight, I would consider that a poor design choice, but there are other ways.

Is there a name for this C++ idiom in which a type vends a wrapper that expands its interface?

I have what is essentially a family of types that share a few common properties with each other. I could actually model this relationship fairly decently with C++ class inheritance. However, I also need to pass and store these objects all around my code, and keeping every instance as a polymorphic heap reference is a pain.
Here's the initial situation:
Enumeration type with values for all "subclasses":
enum class PhoneType {
landline,
cell
}
Type that's stored and passed around a lot:
class Phone {
public:
static Phone landline(PhoneNumber number) {
return Phone(PhoneType::landline, number);
}
static Phone cell(PhoneNumber number, optional<AppList> apps) {
return Phone(PhoneType::cell, number, apps)
}
PhoneType type() { return _type; }
PhoneNumber number() { return _number; }
private:
PhoneType _type;
PhoneNumber _number;
optional<AppList> _apps;
Phone(PhoneType type, PhoneNumber number) :
_type(type), _number(number)
{}
Phone(PhoneType type, PhoneNumber number, optional<AppList> apps) :
_type(type), _number(number), _apps(apps)
{}
};
PhoneType enumerates different possible types of Phones, which all have a PhoneNumber and may or may not have an AppList.
The issue is how to go about giving the outside world access to a phone's AppList once the caller is sure that it's dealing with a cell phone. Note that I don't want to simply vend the optional type, as this pushes a lot of error checking code into the calling function(s), which is not what I want (in the majority of cases, the caller knows the PhoneType of the Phone it's being passed without even having to check, so vending an optional<> is just unnecessary pain).
I could just add the extra accessors to the Phone class, and document that they throw/crash/etc. if the receiving Phone doesn't represent a cell phone. However, in the real code there are many more such attributes that would require more accessors, and each of these accessors is not at all clear about its preconditions when read at a call site.
Long story short, after a bit of consideration I ended up with this idiom:
Before the definition of Phone:
class CheckedPhoneRef {
public:
CheckedPhoneRef() = delete;
Phone& phone() const { return * _phone; }
protected:
Phone* _phone;
CheckedPhoneRef(Phone* phone) : _phone(phone) {}
private:
friend class Phone;
};
class LandlineCheckedPhoneRef : public CheckedPhoneRef {
public:
using CheckedPhoneRef::CheckedPhoneRef;
};
class CellCheckedPhoneRef : public CheckedPhoneRef {
public:
using CheckedPhoneRef::CheckedPhoneRef;
AppList apps() const; // accesses private member of referenced Phone
};
In Phone's public section:
// (Comment above declarations in header):
// These assert that this Phone is of the correct PhoneType.
LandlineCheckedPhoneRef landline_ref() {
assert(_type == PhoneType::landline);
return LandlineCheckedPhoneRef(this);
}
CellCheckedPhoneRef cell_ref() {
assert(_type == PhoneType::cell);
return CellCheckedPhoneRef(this);
}
// (Plus const versions)
In Phone's private section:
friend LandlineCheckedPhoneRef;
friend CellCheckedPhoneRef;
Now it is rather clear what assumptions are being made at any given call site: if I say phone.cell_ref() then I'm clearly asserting that this phone is a cell phone, e.g.,
void call(Phone& phone) {
if (phone.type() == PhoneType::cell) {
if (has_facetime(phone.cell_ref())) ...
} else {
...
}
}
bool has_facetime(CellCheckedPhoneRef cell_phone) {
return cell_phone.apps() ...
}
(Dumb example, but you get the point. I know I could use a visitation pattern here, but the real code isn't quite like this.)
I like this design for what I'm doing. Problem is, I don't quite know what to name the vended wrapper types. I'm currently using the pattern of LandlinePhoneLens, CellPhoneLens, etc., but I know that "lens" already has other meaning in programming. Perhaps this isn't a big issue, but I wanted to ask to be sure I'm not missing a more established naming scheme.
Is there an established name for this pattern/idiom in which a type vends a wrapper that expands its interface?
Your intent is unfortunately not fully clear to me.
At first, I thought that you'd just reinvented the decorator pattern, in which you add dynamically some responsibilities (accessor) to an existing object.
But looking more closely, I think that it all just looks like an anti-pattern, a dependency mess, and a flawed design: eveytime that in the base class you need to be friend of derived class, you should have alarm bells starting to ring.
Instead of looking for a name, you'd better engineer a cleaner design. Forget the enum, and go for an abstract Phone base class, with abstract functions corresponding to what every phone shall be able to do. Then create two derived concrete classes: LandLine and CellPhone, both inheriting from Phone.
Now you could consider that getting the list of apps is a common functionality of all kind of phones, and that a LandLine just returns an empty list. All your code would then just use build in polymorphism to do the job in a proper an extensible way:
If tomorrow, someone would invent a TelepathyPhone, you'd just need to impelement the common functions required by the abstract interface, and all the using code would still work unchanged.
In the worst case, if you'd really need to call a very specific class dependent function that was totally unknown in the common interface (e.g. TelepathyPhone::displayBrainWavelength()), you could go for an if using dynamic_cast. At least you'd avoid to create a new enum everytime you invent a new derived class.

Prevent breaking encapsulation

I have this class:
class Phone {
private:
string producer, color;
int weight, dimension;
public:
Phone(string &producer, string &color, int &weight, int &dimension):
producer(producer), color(color), weight(weight), dimension(dimension) {};
Phone():
producer(""), color(""), weight(0), dimension(0) {};
virtual ~Phone() {};
string getProducer(void) const;
string getColor(void) const;
int getWeight(void) const;
int getDimension(void) const;
virtual void displayInfo(void) const;
};
The problem is here caused by the fact that I expose the internal implementation of the object via getters.
But how can I prevent this?
Because usually in my code, I need to know some private data from my object (for comparision is one example), and that's why I use getters.
So then I rewrite the class to something like this:
class Phone {
private:
string producer, color;
int weight, dimension;
public:
Phone(string &producer, string &color, int &weight, int &dimension):
producer(producer), color(color), weight(weight), dimension(dimension) {};
Phone():
producer(""), color(""), weight(0), dimension(0) {};
virtual ~Phone() {};
bool isTheProducer(string& producer) const { return this->producer == producer };
bool hasWeight(int& weight) const { return this->weight == weight };
bool hasDimension(int& dimension) const { return this->dimension == dimension };
virtual void displayInfo(void) const;
};
Is this a better design (by the fact that I don't get the actual private value)?
As you might have seen from the other answers and comments, the answer is: It depends.
In fact, it depends mainly on the usecases where your class is used. Let's stick first to the example given in the question, the comparison of objects. Since it is not clearly visible from the question if we want to compare two phone objects or just a specific data member I will discuss both situations here.
Comparing a data member to out-of-class data
Let's take this usecase where we search for all phones with a weight bigger than x(just pseudocode):
for (Phone& p in phoneList) {
if (p.getWeight() > x) {
cout << "Found";
}
}
Then the first class example is perfectly fine, since this is not an intrinsic feature of the phone, and thus the phone class is not responsible for handling it. In addition, the result does not expose more than absolutely required for the task.
Comparing two phone objects
In this case both code examples are equally good (or in this case equally bad). In both cases the user has to know a lot of details about how phones are represented to compare all necessary members. If in a later revision a new member is added to the class, every code segment that compares two phones has to be adapted. To overcome this, one can add a function to the class that does exactly the comparison.
class Phone {
private:
string producer, color;
int weight, dimension;
public:
bool IsEqualTo(const Phone& other)
{
return (producer == other.producer && color == other.color &&....);
}
Non comparitive usecase
But let's go to a more advanced example. Let's assume the following task: A user enters the pin to a phone and if it is the correct one, the phone should unlock. Let's assume a very naive approach:
class Phone
{
private:
int pin;
bool unlocked;
public:
int getPin() { return pin; }
void unlock() { unlocked = true; }
};
and the corresponding call
if (phone.getPin() == enteredPin)
phone.unlock();
In this case we have a totally different situation. Here we need to consider the "tell, don't ask" rule, which basically says that it is a bad design to query the state of an object first, make a decision and then tell the object what to do. Instead we should only tell the object what we want, and let it do the work for us. In this usecase this is obvious, since unlocking the phone only when the pin is correct is a responsibility of the phone, not of the user that uses the phone class. But in more complex scenarious many programmers will do exactly what I described here.
Back to the problem: A good solution here would be for example
class Phone
{
private:
int pin;
bool unlocked;
public:
void CheckPin(int enteredPin) {
if (pin == enteredPin)
unlocked = true;
}
};
with the code
phone.CheckPin(enteredPin);
Hope this helps, and thanks to #KonradRudolph for pointing to the "tell, don't ask rule". Feel free to help me to improve the answer per commenting on it :)
The first one, even with getter, is encapsulated. Consider the color() method, which returns a string. Even if you change the implementation of Phone such that you store the color as an enum rather than a string, your method can still return a string if you do some sort of conversion first. The important part is that you can change the implementation of color() and the underlying storage without users of the class needing to change.
Compare to a class that stores color as a publicly accessible string. If you later change the data member to an enum, you need to modify every location that uses the color. This is less of a property of encapsulation and more a property of separating interface from implementation.
Encapsulation allows controlling of attributes exclusively via methods within the class. Both examples are encapsulated.

Best way to change from base class to derived class

I know this is asked in various ways on this forum, but I still can't quite figure out the best way to go about what I need to do (after reading various other posts). So I have decided to seek further advice!
I have a message class hierarchy, something like (omitted most details):
class MsgBase
{
public:
uint8_t getMsgType(void);
protected: // So that derived classes can access the member
char _theMsgData[100];
}
class MsgType1 : public MsgBase
{
}
class MsgType2 : public MsgBase
{
}
So what happens is I received a block of message data and I use it to create my message. But I don't know which message to create until I read out the message type. So I end up with:
MsgBase rxMsg(rxData);
if (rxMsg.getMsgType() == 1)
{
// Then make it a MsgType1 type message
}
else if (rxMsg.getMsgType() == 2)
{
// Then make it a MsgType2 type message
}
This is the bit I am stuck on. From what I have read, I cannot dynamical cast from base to derived. So my current option is to instantiate a whole new derived type (which seems inefficient), i.e.:
if (rxMsg.getMsgType() == 1)
{
// Now use the same data to make a MsgType1 message.
MsgType1 rxMsg(rxData);
}
Is there a way that I can look at the data as the base class so that I can determine its type and then "molymorph" it into the required derived type?
Thanks,
Fodder
What is rxData? I assume it's just a blob of data, and you should parse it to determine the message type before you create any message object. And depending on if the message data has always the same length you should consider using std::array or std::vector to pass the data blob around.
typedef std::vector<char> MsgDataBlob;
class MsgBase
{
public:
uint8_t getMsgType();
MsgBase(MsgDataBlob blob) : _theMsgData(std::move(blob)) {}
protected: // So that derived classes can access the member
MsgDataBlob _theMsgData;
};
//derived classes here...
//this could be either a free function or a static member function of MsgBase:
uint8_t getMessageType(MsgDataBlob const& blob) {
// read out the type from blob
}
std::unique_ptr<MsgBase> createMessage(MsgDataBlob blob) {
uint8_t msgType = getMessageType(blob);
switch(msgType) {
case 1: return make_unique<MsgDerived1>(std::move(blob));
case 2: return make_unique<MsgDerived2>(std::move(blob));
//etc.
}
}
If you want the messages to return the data, but for example MsgType1 should make it all lower case, and MsgTyp2 all upper case you could make a virtual function in MsgBase called, for example,
virtual char *getData();
and this function should be reimplemented in child classes so that it does with the data what you want it to do. This way when you call this function on base class pointer, you will get reimplemented functionality, depending to what type the actual pointer is, at the moment of calling.

C++ design - Network packets and serialization

I have, for my game, a Packet class, which represents network packet and consists basically of an array of data, and some pure virtual functions
I would then like to have classes deriving from Packet, for example: StatePacket, PauseRequestPacket, etc. Each one of these sub-classes would implement the virtual functions, Handle(), which would be called by the networking engine when one of these packets is received so that it can do it's job, several get/set functions which would read and set fields in the array of data.
So I have two problems:
The (abstract) Packet class would need to be copyable and assignable, but without slicing, keeping all the fields of the derived class. It may even be possible that the derived class will have no extra fields, only function, which would work with the array on the base class. How can I achieve that?
When serializing, I would give each sub-class an unique numeric ID, and then write it to the stream before the sub-class' own serialization. But for unserialization, how would I map the read ID to the appropriate sub-class to instanciate it?
If anyone want's any clarifications, just ask.
-- Thank you
Edit: I'm not quite happy with it, but that's what I managed:
Packet.h: http://pastebin.com/f512e52f1
Packet.cpp: http://pastebin.com/f5d535d19
PacketFactory.h: http://pastebin.com/f29b7d637
PacketFactory.cpp: http://pastebin.com/f689edd9b
PacketAcknowledge.h: http://pastebin.com/f50f13d6f
PacketAcknowledge.cpp: http://pastebin.com/f62d34eef
If someone has the time to look at it and suggest any improvements, I'd be thankful.
Yes, I'm aware of the factory pattern, but how would I code it to construct each class? A giant switch statement? That would also duplicade the ID for each class (once in the factory and one in the serializator), which I'd like to avoid.
For copying you need to write a clone function, since a constructor cannot be virtual:
virtual Packet * clone() const = 0;
Which each Packet implementation implement like this:
virtual Packet * clone() const {
return new StatePacket(*this);
}
for example for StatePacket. Packet classes should be immutable. Once a packet is received, its data can either be copied out, or thrown away. So a assignment operator is not required. Make the assignment operator private and don't define it, which will effectively forbid assigning packages.
For de-serialization, you use the factory pattern: create a class which creates the right message type given the message id. For this, you can either use a switch statement over the known message IDs, or a map like this:
struct MessageFactory {
std::map<Packet::IdType, Packet (*)()> map;
MessageFactory() {
map[StatePacket::Id] = &StatePacket::createInstance;
// ... all other
}
Packet * createInstance(Packet::IdType id) {
return map[id]();
}
} globalMessageFactory;
Indeed, you should add check like whether the id is really known and such stuff. That's only the rough idea.
You need to look up the Factory Pattern.
The factory looks at the incomming data and created an object of the correct class for you.
To have a Factory class that does not know about all the types ahead of time you need to provide a singleton where each class registers itself. I always get the syntax for defining static members of a template class wrong, so do not just cut&paste this:
class Packet { ... };
typedef Packet* (*packet_creator)();
class Factory {
public:
bool add_type(int id, packet_creator) {
map_[id] = packet_creator; return true;
}
};
template<typename T>
class register_with_factory {
public:
static Packet * create() { return new T; }
static bool registered;
};
template<typename T>
bool register_with_factory<T>::registered = Factory::add_type(T::id(), create);
class MyPacket : private register_with_factory<MyPacket>, public Packet {
//... your stuff here...
static int id() { return /* some number that you decide */; }
};
Why do we, myself included, always make such simple problems so complicated?
Perhaps I'm off base here. But I have to wonder: Is this really the best design for your needs?
By and large, function-only inheritance can be better achieved through function/method pointers, or aggregation/delegation and the passing around of data objects, than through polymorphism.
Polymorphism is a very powerful and useful tool. But it's only one of many tools available to us.
It looks like each subclass of Packet will need its own Marshalling and Unmarshalling code. Perhaps inheriting Packet's Marshalling/Unmarshalling code? Perhaps extending it? All on top of handle() and whatever else is required.
That's a lot of code.
While substantially more kludgey, it might be shorter & faster to implement Packet's data as a struct/union attribute of the Packet class.
Marshalling and Unmarshalling would then be centralized.
Depending on your architecture, it could be as simple as write(&data). Assuming there are no big/little-endian issues between your client/server systems, and no padding issues. (E.g. sizeof(data) is the same on both systems.)
Write(&data)/read(&data) is a bug-prone technique. But it's often a very fast way to write the first draft. Later on, when time permits, you can replace it with individual per-attribute type-based Marshalling/Unmarshalling code.
Also: I've taken to storing data that's being sent/received as a struct. You can bitwise copy a struct with operator=(), which at times has been VERY helpful! Though perhaps not so much in this case.
Ultimately, you are going to have a switch statement somewhere on that subclass-id type. The factory technique (which is quite powerful and useful in its own right) does this switch for you, looking up the necessary clone() or copy() method/object.
OR you could do it yourself in Packet. You could just use something as simple as:
( getHandlerPointer( id ) ) ( this )
Another advantage to an approach this kludgey (function pointers), aside from the rapid development time, is that you don't need to constantly allocate and delete a new object for each packet. You can re-use a single packet object over and over again. Or a vector of packets if you wanted to queue them. (Mind you, I'd clear the Packet object before invoking read() again! Just to be safe...)
Depending on your game's network traffic density, allocation/deallocation could get expensive. Then again, premature optimization is the root of all evil. And you could always just roll your own new/delete operators. (Yet more coding overhead...)
What you lose (with function pointers) is the clean segregation of each packet type. Specifically the ability to add new packet types without altering pre-existing code/files.
Example code:
class Packet
{
public:
enum PACKET_TYPES
{
STATE_PACKET = 0,
PAUSE_REQUEST_PACKET,
MAXIMUM_PACKET_TYPES,
FIRST_PACKET_TYPE = STATE_PACKET
};
typedef bool ( * HandlerType ) ( const Packet & );
protected:
/* Note: Initialize handlers to NULL when declared! */
static HandlerType handlers [ MAXIMUM_PACKET_TYPES ];
static HandlerType getHandler( int thePacketType )
{ // My own assert macro...
UASSERT( thePacketType, >=, FIRST_PACKET_TYPE );
UASSERT( thePacketType, <, MAXIMUM_PACKET_TYPES );
UASSERT( handlers [ thePacketType ], !=, HandlerType(NULL) );
return handlers [ thePacketType ];
}
protected:
struct Data
{
// Common data to all packets.
int number;
int type;
union
{
struct
{
int foo;
} statePacket;
struct
{
int bar;
} pauseRequestPacket;
} u;
} data;
public:
//...
bool readFromSocket() { /*read(&data); */ } // Unmarshal
bool writeToSocket() { /*write(&data);*/ } // Marshal
bool handle() { return ( getHandler( data.type ) ) ( * this ); }
}; /* class Packet */
PS: You might dig around with google and grab down cdecl/c++decl. They are very useful programs. Especially when playing around with function pointers.
E.g.:
c++decl> declare foo as function(int) returning pointer to function returning void
void (*foo(int ))()
c++decl> explain void (* getHandler( int ))( const int & );
declare getHandler as function (int) returning pointer to function (reference to const int) returning void