【问题标题】:Making one of the inherited protected members private将继承的受保护成员之一设为私有
【发布时间】:2012-09-12 17:17:48
【问题描述】:
class A
{
protected:
    int m_a;
    int m_b;
};

class B: public A
{
};

在 B 类中,我想将 m_a 设为私有。 以下是正确的做法吗

class B:public A
{    
private:
    int m_a;
};

这不会导致m_a 的2 个副本吗?

【问题讨论】:

标签: c++ inheritance


【解决方案1】:

class B 中的 m_a 阴影 class A。它是一个不同的数据成员,所以 B 类实际上有三个intsA::m_aA::m_bB::m_a。在B 中私下访问m_a 的方法是在class B 中私下“使用”A::m_a

class A {
  int m_a;
};

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

class C : public B {
  void foo() { 
    m_a++; // ERROR!
  }
};

【讨论】:

  • 如果是这种情况,我们会收到重新声明错误,对吗?但我似乎没有得到。
  • 一点也不。但它确实将 m_a 与 B 代码隔离为 B 中声明的那个。A 中的那个从那时起被隐藏,除非类解析(A::m_a 或 ::m_a)
  • 不,这不是重新声明:A::m_aB::m_aB 的每个实例中都是独立的成员。不过,名称查找规则可能会令人困惑。
  • @KodeWarrior 如果您想看到名称隐藏在行动中,请在class A 中声明一个函数void foo(),然后在class B 中声明一个int foo
【解决方案2】:

调整成员访问控制的正确方法是使用using declaration

class B: public A {    
private:
    using A::m_a;
}

只写int m_a; 确实会产生m_a 的两个副本,而派生类可以通过写A::m_a 来访问Am_a 副本。

【讨论】:

  • 但是,从B 派生class C,您仍然可以通过使用A::m_a 明确限定m_a 来访问它。
  • @AlexanderTobiasHeinrich 没有使用一致的编译器;参见例如liveworkspace.org/code/9ac3b1e42038bdd8cb5662fff0aa5753
  • 俗话说,“防墨菲,防马基雅维利”。如果一个班级客户使用A::m_a 成功地绕过了保护措施并且事情出了差错,那么,只是沙漠。
  • @CraigNelson C++11 在这里不是必需的。只是一个符合 C++03 的编译器。
  • 不开玩笑。一直以来……那些我一直在寻找的机器人。谢谢!
【解决方案3】:

此代码在 B 类中创建三个 int 存储。

m_a 的声明创建了一个新变量 - 这里在 c++ 中没有重新声明问题,因为声明在不同的范围内,更具体地说,A::m_a 与 B::m_a 不同。

【讨论】:

    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 2016-06-12
    • 2014-06-09
    • 2012-10-03
    • 2010-10-26
    相关资源
    最近更新 更多