Home > Net >  How to construct derived class from base?
How to construct derived class from base?

Time:09-12

Is there a way to cast base class to derived, calling default constructor? I'm receiving network data, writing it to packets, then calling protocol function which I wish to parse data differently.

class BasePacket {
protected:
    std::vector<char> data;
public:    
    BasePacket(){data.reserve(2048);}
    BasePacket(char* _data, int len){ data.assign(&data[0], &data[len]); }
};

class ActionPacket : public BasePacket {
public:
    char Action;
    char Job;
    ActionPacket(){
        Action = data[0];
        Job = data[1];
    }
};

I would like to do something like:

void ProcessPacket(BasePacket& packet){
    if (packet.data[0] == 1){
        auto t = (ActionPacket)packet;
        if(t.Job == 1){
            //dosmth
        }
    }
 
    if (packet.data[0] == 2){
        auto t = (OtherPacket)packet;
        if(t.smth){
            //do another smth
        }
    }
}

CodePudding user response:

If your instance is initially a BasePacket object, why not just code like ActionPacket::ActionPacket(BasePacket&)? That's because ActionPacket have some members that BasePacket doesn't have, reallocation seems inevitable. Just like this:

class ActionPacket
{
    ActionPacket(BasePacket& basePacket) :BasePacket(basePacket), Action(data[0]), Job(data[1]) {};
};
// assuming there is a legal BasePacket object called basePacket
auto actionPacket = ActionPacket{basePacket};

BUT, if you are sure that this BasePacket object will ONLY be used for constructing ActionPacket here and will never be used afterwards, you can write ActionPacket::ActionPacket(BasePacket&&) and use std::move like this:

class ActionPacket
{
    ActionPacket(BasePacket&& basePacket) :BasePacket(std::move(basePacket)), Action(data[0]), Job(data[1]) {};
};
// assuming there is a legal BasePacket object called basePacket
auto actionPacket = ActionPacket{std::move(basePacket)};

This will be more efficient since std::vector is moved but not re-constructed.

If your instance is initially an ActionPacket object, and there are no virtual methods, static_cast is acceptable; But if there are some virtual methods, dynamic_cast is what you want.

  • Related