【问题标题】:Can I access a base classes protected members from a static function in a derived class?我可以从派生类中的静态函数访问受保护的基类成员吗?
【发布时间】:2011-11-10 13:18:48
【问题描述】:

我有一个程序,我需要在其中创建一个在 dll 和一些应用程序代码之间共享的基类。然后我有两个不同的派生类,一个在 dll 中,一个在主应用程序中。它们中的每一个都有一些静态成员函数,它们对 nase 类中的数据进行操作。 (它们需要是静态的,因为在其他地方用作函数指针)。我的问题最简单的形式如下所示。

class Base {
protected:
  int var ;
};

class Derived : public Base {
  static bool Process( Base *pBase ) {
    pBase->var = 2;
    return true;
  }
};

我的编译器抱怨我无法访问 pBase 的受保护成员,即使 Derived 具有对 Base 的受保护访问。有什么办法可以解决这个问题还是我误解了什么? 我可以公开 Base 变量,但这会很糟糕,因为在我的真实实例中,这些是分配的内存块和用于保护它以进行多线程处理的信号量。

帮助?

【问题讨论】:

  • Accessing parent's protected variables 的可能重复项。这与函数是否为static 无关,而是因为访问基成员的参数不是Derived 类型。
  • 静态函数的参数必须是基类的,以符合函数指针的调用要求。也许我可以使用动态演员来解决这个问题
  • 如果您可以控制仅使用指向Base 对象的指针调用该函数,这些对象是Derived 对象的基类子对象,您可以使用static_castBase* 转换到函数体中的Derived*。否则,您必须是 Basefriend,或者您可以将 var 更改为公开。如果你不能做任何这些,那么你就被困住了。

标签: c++ static derived access-specifier


【解决方案1】:

一般来说(不管函数是否是静态的),一个 派生类的成员函数只能访问受保护的基类 其类型的对象的类成员。它无法访问受保护的 如果静态类型不是派生类的,则为基类的成员 (或从它派生的类)。所以:

class Base {
protected:
    int var;
 } ;

class Derived : public Base {
    static void f1( Derived* pDerived )
    {
        pDerived->var = 2; // legal, access through Derived...
    }
    static bool Process( Base *pBase )
    {
        pBase->var = 2 ;  // illegal, access not through Derived...
    }
} ;

【讨论】:

  • 所以我猜因为我的静态函数用于函数指针并且参数需要是基类,我应该能够动态转换为派生类。
  • 如果基类至少有一个虚函数,是的。 (或者您可以更改函数以获取Derived*,并将dynamic_cast 留给客户端。)
【解决方案2】:

访问说明符适用于Derived 类句柄(引用/指针/对象)而不是Derived 类本身的方法。即使该方法不是static,您最终也会遇到同样的错误。因为您没有使用派生句柄访问varDemo.

正确的方法是提供setter方法:

class Base {
protected:
  int var ;
public:
  void setVar(const int v) { var = v; } // <--- add this method
};

注意:还有一种出路,但我不确定它是否优雅。

(static_cast<Derived*>(pBase))->var = 2;

【讨论】:

  • 不幸的是,在我的真实类中,基类中的数据实际上是一些内存块和用于多线程访问的信号量负载。对信号量和内存块使用 getter 和 setter 似乎非常麻烦,因为基数中可能有 10-15 个变量。
猜你喜欢
  • 2020-12-24
  • 2014-08-27
  • 1970-01-01
  • 2022-07-20
  • 1970-01-01
  • 2019-01-20
  • 2012-08-29
  • 2016-04-07
  • 2018-11-27
相关资源
最近更新 更多