psteiner
psteiner

Reputation: 187

C++ how to access a protected base class method through an instance of the derived class

Given the following c++ classes:

// base class
class A {
protected:
    void writeLogEntry(const std::string& message);
};

// derived class
class B : public A { };

// c.h
class C {
   myMethod();
}

// c.cpp - uses B
C::myMethod()
{
    B b;
    b.writeLogEntry("howdy");
}

As expected, class C fails to compile with the error "cannot access protected member declared in class 'A'.

Should I a) make the method A::writeLogEntry public, or b) make a public method B::writeLogEntry(message) that passes the message param to A::writeLogEntry(message), or c) something else entirely?

Thanks

P

Upvotes: 1

Views: 1531

Answers (8)

Bodislav Nicolae
Bodislav Nicolae

Reputation: 111

If you don't want to write a new function in B, put this

class B : public A 
{
public:
     using A::writeLogEntry;
};

and you can do

B b;
b.writeLogEntry();

Upvotes: 2

Raymond
Raymond

Reputation: 609

I'd prefer declare writeLogEntry public in base class. Because it tends to be part of the accessible interface.

If it's declared in derived class, then the user of this method is tightly bound to the derived class. Usually, it's a better idea to rely on abstraction.

Upvotes: 0

Jagannath
Jagannath

Reputation: 4025

Apart from making class C a friend of class A, if writeLogEntry() is virtual in class A, and if it is overridden in class B with public access specifier,then it can be accessed from class C.

class A
{
  protected:
  virtual void writeLogEntry() { cout << "A::mymethod" << endl; }
};
class B : public A
{
  public:
       virtual void writeLogEntry() { cout << "B::mymethod" << endl; }
};

class C 
{
 public:
  void writeLogEntry()
  {
     B b;
     b.writeLogEntry();
  }
};

Upvotes: 0

Igor Zevaka
Igor Zevaka

Reputation: 76500

I think it's really up to you how to design your class hierarchy. If you are using inheritance and you don't mind the function being accessable from an instance of class A then there is no point to delegate writeLogEntry. Might as well make it public in the base class:

class A {
public:
    void writeLogEntry(const std::string& message);
};

If don't want to writeLogEntry being accessable from an instance of class A then you have delegate:

class B : public A { 
    void writeLogEntry(const std::string& message){ A::writeLogEntry(message); }
};

Do some research into Inheritance vs. Composition. You might get a few ideas on how to structure your classes. Some people prefer to avoid inheritance as much as possible and in this case have class B own an instance of class A and delegate the relevant methods. IMHO there are genuine cases for when inheritance is appropriate, depends on the nature of your particular beast.

Upvotes: 3

Jesse Emond
Jesse Emond

Reputation: 7480

I'd personally go with b). Make a public method in B to call A's writeLogEntry. But that's just me! :) Also, you could use "friend class C" in the A class like the others said.

Upvotes: 0

Andreas Bonini
Andreas Bonini

Reputation: 44752

Other folks already answered, but I suggest you read http://www.parashift.com/c++-faq-lite/friends.html for more information about friends!

As a matter of fact, read the entire FAQ while you're at it!

Upvotes: 0

Kornel Kisielewicz
Kornel Kisielewicz

Reputation: 57555

You can befriend class C with A.

class A {
protected:
    friend class C;
    void writeLogEntry(const std::string& message);
};

AFAIR, should work.

Upvotes: 2

Klaim
Klaim

Reputation: 69682

class A {
protected:
    void writeLogEntry(const std::string& message);


    friend class C;
};

Upvotes: 0

Related Questions