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
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.
You can befriend class C with A.
class A {
protected:
friend class C;
void writeLogEntry(const std::string& message);
};
AFAIR, should work.
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();
class A {
protected:
void writeLogEntry(const std::string& message);
friend class C;
};
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!
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.
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();
}
};
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.
精彩评论