【问题标题】:Private implementation for public interface method [duplicate]公共接口方法的私有实现[重复]
【发布时间】:2016-01-19 11:25:41
【问题描述】:

我遇到了一段代码,其方法通过公共接口公开,而实现是私有的。我不确定预期的行为应该是什么。简化示例:

#include <iostream>

class Interface
{
public:
    virtual ~Interface() {}
    virtual void myIfMethod() = 0;
};

class Derived : public Interface
{
private:
    void myIfMethod(){std::cout << "private method invoked via public interface" << std::endl;}
};

int main()
{
    Interface* myObj = new Derived;
    myObj->myIfMethod();
    delete myObj;
    return 0;
}

此示例编译并执行时没有警告:http://ideone.com/1Ouwk4

这是正确且定义明确的行为吗?如果是这样,为什么?

请注意,问题不是关于具有公共实现的私有接口方法(关于 SO 有多个此类问题),而是反过来。

【问题讨论】:

  • 没有错。这是毫无意义的,客户端代码总是可以转换为接口类型并进行调用。类没有义务使接口方法起作用,它可以抛出“未实现”异常。然后,您最好将其声明为私有以降低暴露风险。
  • 对此也有很多疑问。访问保护是编译时检查,你使用的是Interface的接口,函数是公共的。

标签: c++ interface


【解决方案1】:

C++ 标准草案

访问虚函数 [class.access.virt]

1 虚函数的访问规则(第 11 条)由其声明决定,不受 稍后覆盖它的函数的规则。

2 在调用点使用用于表示为其调用成员函数的对象的表达式类型(上例中的 B*)检查访问。成员函数在定义它的类中的访问(上例中的 D)通常是未知的。

函数是通过Interface类型的指针调用的,其中成员函数是公共的,所以允许访问。派生成员函数的访问是未知的,没有任何影响。就标准而言,该行为是正确且定义明确的。

当然,将覆盖函数定义为私有可能毫无意义,因为无论如何它都可以通过虚拟调度访问。

【讨论】:

  • 关于最后一点毫无意义;它可能有用,因此您需要使用该界面。所以如果你构建了具体的类,你就不能调用它的方法,因为它们是私有的。
  • @user3282085 当然,但这会引发一个问题:阻止直接将接口与具体类一起使用有什么意义吗?对我来说似乎是无用的悲观。
  • 你是对的;可能是不必要的预防。就像有人可以 static_cast(&concrete) 一样。谢谢! :)
猜你喜欢
  • 2014-09-21
  • 1970-01-01
  • 2019-08-26
  • 2014-02-01
  • 2019-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-19
相关资源
最近更新 更多