【问题标题】:How to ensure in run-time that a member function in an inherited class is private? (C++, gcc)如何在运行时确保继承类中的成员函数是私有的? (C++, gcc)
【发布时间】:2011-09-12 20:56:04
【问题描述】:

A 是基类,B 是继承类。 A 从与 boost::bind+boost::function 绑定的 B 中获取成员函数指针,以便稍后从其他基类函数存储和执行。 AB 类位于不同的包含文件中。我想限制从 A 实现继承类的开发人员,继承类中的绑定成员函数指针是私有函数。环境为C++、gcc 4.x和Linux。

示例:

------ INCLUDE FILE -----

#include <boost/bind.hpp>
#include <boost/function.hpp>

struct A
{
protected:
    void Register(const char* name, boost::function<void()> FuncPtr)
    {
      // (I am not intended to pass the name argument, but probably somebody
      // knows something gcc magic which would use it to solve the problem.)
      // I want to ensure that FuncPtr points to a private member
      // function. What can be known: "B::CalledFunction" string and FuncPtr.
      // If it is not a private member function then drop an error message
      // during run-time or during compilation (???).
    }
};

------ OTHER INCLUDE FILE -----
...

struct B : public A
{
    B() : A()
    {
      Register("B::CalledFunction", boost::bind(&B::CalledFunction, this));
    }

private:
    void CalledFunction()
    {
    }
};

在之前/而不是简单地直接调用A::Register() 之前,也可以欣赏任何类型的宏魔术或类似的东西。

【问题讨论】:

  • 为什么您要强制执行此操作?
  • 在 C++11 中,访问规范的规则被更改为在 SFINAE 之前应用,因此您将有机会进行一些宏 hack 来检测函数是否是私有的。但是我觉得不值得,为什么要设置这样的人为限制?
  • 这样做的目的是什么?为什么不按照应有的方式使用继承?
  • 目的:在我的情况下,继承的类会实现新的功能,绑定并存储在基类中以便以后调用它们,但我想阻止使用B类的开发人员调用直接绑定这些函数。
  • @kecsap :派生类的成员函数的可访问性不应该取决于派生类的作者吗?为什么基类应该关心这两种方式?

标签: c++ linux gcc private-members


【解决方案1】:

我将提出一个基于真正使用继承的替代方案,而不是扩展 cmets

#include <iostream>
#include <memory>

class A
{
  public:
    void call_a() { some_func_a(); }
  private:
    virtual void some_func_a() = 0; // pure virtual
};

class B : public A
{
  private:
    void some_func_a() { std::cout << "B::some_func_a" << std::endl; }
};

int main(void)
{
  std::auto_ptr<A> a(new B);
//  a->some_func_a();  // causes compiler error
  a->call_a();
}

如果您在B 中遗漏了some_func_a 的定义,则在尝试实例化B 时会出现编译器错误。

【讨论】:

    【解决方案2】:

    很遗憾,您要求的限制是不可能的。访问限制只存在于编译时,而不是运行时;他们唯一要做的就是控制(基于词法范围)可以引用哪些标识符。

    由于生成这些绑定成员函数的调用上下文显然可以访问其所有成员函数,因此您无法在本地区分私有成员函数和公共成员函数 - 这排除了任何宏 hack。此外,成员函数指针不保留访问控制信息(这就是为什么您可以从另一个类调用指向私有成员函数的指针的原因)。因此,也无法在其他地方进行检查。

    您可以将其作为编译器传递来实现,例如clang,因为信息在编译时可用;但是,这对于普通的 C++ 编译器是不可能的。但是,这可能容易出现误报和误报,因为这是一个问题的情况有些不明确(如果某些派生类B真的想要绑定公共成员函数怎么办? ,它会在其他地方使用吗?)

    【讨论】:

      猜你喜欢
      • 2023-03-03
      • 1970-01-01
      • 2011-02-26
      • 2011-02-10
      • 2020-09-01
      • 1970-01-01
      • 2014-11-27
      • 2019-03-13
      • 2016-07-15
      相关资源
      最近更新 更多