【问题标题】:How and why is it possible to change access level of a member?如何以及为什么可以更改成员的访问级别?
【发布时间】:2011-05-04 22:02:11
【问题描述】:

我昨天(在一些帮助下)完成了这样的编码:

#include <iostream>

using namespace std;

class A
{
    public:
        virtual void foo(){cout << "A::foo\n";}
};

class B : private A
{
    private:
        virtual void foo(){ cout << "B::foo\n";}
        void DoSomething(SomeOtherClass& o){o.DoSomething(*static_cast<A*>(this));}
};

我尝试改变继承方式:

class B : public A
{
    private:
        virtual void foo(){ cout << "B::foo\n";}
};

int main()
{
    A* a = new B;
    a->foo();
}

这仍然有效。我预计会出现编译时错误。请告诉我为什么这是可能的以及可能的用途是什么?由于第一种情况,我知道一种用途 - 您可以为不同的类公开不同的接口。

编辑:

在第二种情况下,输出为B::foo

【问题讨论】:

  • 您认为错误在哪里?关于将函数声明为私有?还是在函数的调用上?
  • 我很感兴趣。希望有一个答案可以解释此功能的可能用途(?)。一种用法可能是强制程序员将类 B 实例化为指向基类 A 的指针,以便使用它的接口。但为什么那会是一件好事,我不知道。
  • @PigBen:在第二种情况下,我预计fooB 的定义会出现错误。
  • @manneorama:检查我昨天发布的这个问题。正是从它我得到了这个:)。 stackoverflow.com/questions/4084772/…

标签: c++ oop


【解决方案1】:

可能无法直接回答您的所有问题,但我决定将其放在这里以供将来参考。也请谨慎对待,因为这是基于我对 C++ 标准世界中发生的事件的理解,而不是实际情况。

阅读this。我没有 ARM,但这篇文章提供了必要的细节。

C++0x 中的注释 115 说

115) 访问声明是 已弃用;成员使用声明 (7.3.3) 提供更好的方法 做同样的事情。在早些时候 C++ 语言版本,访问 声明更加有限;他们 被概括并等效 使用利益声明 简单的。程序员是 鼓励使用 using 声明, 而不是新的能力 访问声明,在新代码中。

总结:

我认为 ARM 最初是禁止的:

不能使用访问声明 限制对成员的访问 在基类中可访问,也不能 它用于启用对 中不可访问的成员 基类。

但后来我猜想当标准演变时this was eventually allowed

【讨论】:

【解决方案2】:
using namespace std; 

class A 
{ 
    public: 
        virtual void foo(){cout << "A::foo\n";} 
}; 

class B : public A 
{ 
    private: 
        virtual void foo(){ cout << "B::foo\n";} 
}; 

int main() 
{ 
    A* a = new B; 
    a->foo(); 
} 

这是有效的,因为在编译时编译器只能看到a 是指向基类A 的指针,而foo() 是在a 上调用的公共方法,这是完全有效的。虚拟绑定在编译后的运行时动态发生,此虚拟绑定决定实际调用是对B::foo() 而不是A::foo(),这是使用虚拟的性能损失。

【讨论】:

  • 很容易看出它为什么起作用。但如果不允许在 B 中将 foo() 设为私有,那将更有意义。所以我认为问题是,该设计决策背后的基本原理是什么。
  • @kotlinski:有一个非常著名的设计模式,称为“模板方法”模式,它利用了这个基本原理。请检查一下。
  • 我看不出这与模板方法设计模式之间的联系。
  • 模板方法模式在基类和派生类中都使用私有。这就说得通了。在这种情况下,将访问权限从公共更改为私有似乎令人困惑。私有并不意味着任何有用的东西——它仍然可以通过基类调用所谓的“私有”函数。
猜你喜欢
  • 2016-10-26
  • 2014-03-13
  • 2012-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-05
  • 2012-12-09
相关资源
最近更新 更多