C ++如何通过派生类的实例访问受保护的基类方法

时间:2009-12-18 00:19:33

标签: c++

给出以下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

8 个答案:

答案 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。因为它往往是可访问界面的一部分。

如果它在派生类中声明,则此方法的用户与派生类紧密绑定。通常,依靠抽象是一个更好的主意。