给出以下c ++类:
// 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");
}
正如预期的那样,C类无法编译,错误“无法访问在类'A'中声明的受保护成员。
我应该a)使方法A :: writeLogEntry公开,或b)创建一个公共方法B :: writeLogEntry(message)将消息参数传递给A :: writeLogEntry(消息),或c)完全不同于其他东西?
由于
P
答案 0 :(得分:3)
我认为这取决于你如何设计你的类层次结构。如果您正在使用继承,并且您不介意可以从类A
的实例访问该函数,那么就没有必要委派writeLogEntry
。不妨在基类中公开它:
class A {
public:
void writeLogEntry(const std::string& message);
};
如果不希望writeLogEntry
可以从类A
的实例访问,那么您有代表:
class B : public A {
void writeLogEntry(const std::string& message){ A::writeLogEntry(message); }
};
对Inheritance vs. Composition进行一些研究。您可能会对如何构建类有一些想法。有些人更愿意尽可能地避免继承,在这种情况下,类B
拥有类A
的实例并委托相关方法。恕我直言,有适当的继承适用的真实案例,取决于你的特定野兽的性质。
答案 1 :(得分:2)
你可以和A一起成为C级的朋友。
class A {
protected:
friend class C;
void writeLogEntry(const std::string& message);
};
AFAIR,应该有用。
答案 2 :(得分:2)
如果您不想在B中写一个新功能,请将此
class B : public A
{
public:
using A::writeLogEntry;
};
你可以做到
B b;
b.writeLogEntry();
答案 3 :(得分:0)
class A {
protected:
void writeLogEntry(const std::string& message);
friend class C;
};
答案 4 :(得分:0)
其他人已经回答,但我建议你阅读http://www.parashift.com/c++-faq-lite/friends.html了解有关朋友的更多信息!
事实上,请在阅读整个常见问题解答时使用它!
答案 5 :(得分:0)
我亲自去b)。在B中创建一个公共方法来调用A的writeLogEntry。但那只是我! :) 另外,你可以在A类中使用“朋友类C”,就像其他人说的那样。
答案 6 :(得分:0)
除了使类C成为类A的朋友之外,如果writeLogEntry()在类A中是虚拟的,并且如果它在具有公共访问说明符的类B中被覆盖,则可以从类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();
}
};
答案 7 :(得分:0)
我更喜欢在基类中声明writeLogEntry public。因为它往往是可访问界面的一部分。
如果它在派生类中声明,则此方法的用户与派生类紧密绑定。通常,依靠抽象是一个更好的主意。