Argent
Argent

Reputation: 837

C++ Inheriting Protected Members

Okay, for some reason inheritance is not working the way I thought it would work, and it's vexing me strongly. Let's say I have two classes - BaseMessage and DerivedMessage. Same namespace. I define them in messages.hpp as such:

class BaseMessage
{
public:
    BaseMessage();
    virtual ~BaseMessage();

protected:
    BString<2> _messageType;
};

class DerivedMessage : public BaseMessage
{
public:
    DerivedMessage();
    virtual ~DerivedMessage();

protected:
    BString<2> _informationType;
};

The idea is, I have multiple derived messages, all with unique fields (which I haven't included here), but they ALL have a message type. So I figured I'll stick messageType into the parent class and have all of its children inherit it. Except I am obviously doing it wrong, because if we look at messages.cpp:

BaseMessage::BaseMessage() { }

BaseMessage::~BaseMessage() { }

/* #TODO: Implement helper functions */

/* *** *** *** *** *** *** *** *** *** *** *** ***  */

DerivedMessage::DerivedMessage()
: _messageType("SS")
{

}

DerivedMessage::~DerivedMessage() { }

the compiler throws a fit about "class ‘full::namespace::DerivedMessage’ does not have any field named ‘_messageType’"

The only other thread I found somewhat useful was one where the problem was in trying to access the parent's protected attribute from the child - but I don't think that's my case, I am trying to set DerivedMessage's _messageType, the only thing I need the parent BaseMessage is to declare it.

Or am I going about it poorly? I just thought, maybe I need to work with virtual attributes instead of protected ones?

Upvotes: 2

Views: 171

Answers (2)

Mike Seymour
Mike Seymour

Reputation: 254431

A member can only be initialised by the class that contains it, not a derived class. So initialise it in the base class constructor:

explicit BaseMessage(BString<2> type) : _messageType(type) {}

and pass this through from the derived class:

DerivedMessage() : BaseMessage("SS") {}

Upvotes: 4

jrok
jrok

Reputation: 55395

_messageType, being a member of BaseMessage subobject of DerivedMessage, needs to be initialized by BaseMessage's constructor:

class BaseMessage
{
public:
    BaseMessage();
    BaseMessage(const char* c) : _messageType(c) {}   // <--- here
    virtual ~BaseMessage();

protected:
    BString<2> _messageType;
};

Then, in derived class' constructor, write a forwarding call like this:

DerivedMessage::DerivedMessage()
: BaseMessage("SS")
{  }

Upvotes: 7

Related Questions