繁体   English   中英

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

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

给定以下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(message),或者c)完全将其他方法设为其他?

谢谢

P

我认为如何设计类层次结构真的取决于您。 如果使用继承,并且不介意从类A的实例访问该函数,则没有必要委派writeLogEntry 也可以在基类中将其公开:

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

如果不想从类A的实例访问writeLogEntry ,则可以委托:

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

继承与组合进行一些研究。 您可能会得到一些有关如何构建类的想法。 有些人希望尽可能避免继承,在这种情况下,类B拥有类A的实例并委托相关方法。 恕我直言,在某些情况下,真正适合继承的情况取决于您的特定野兽的性质。

您可以与A成为C类朋友。

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

飞行,应该工作。

如果您不想在B中编写新函数,请输入

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

你可以做

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


    friend class C;
};

其他人已经回答了,但是我建议您阅读http://www.parashift.com/c++-faq-lite/friends.html ,以获取有关朋友的更多信息!

事实上,在阅读时,请阅读整个FAQ。

我个人会选择b)。 在B中创建一个公共方法来调用A的writeLogEntry。 但这就是我! :)另外,您可以像其他人一样在A类中使用“朋友C类”。

除了让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();
  }
};

我更愿意在基类中声明writeLogEntry公共。 因为它倾向于成为可访问界面的一部分。

如果在派生类中声明,则此方法的用户将紧密绑定到派生类。 通常,最好是依赖抽象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM