【问题标题】:C ++ Child class cannot inherit private member from Father class?C++子类不能从父类继承私有成员?
【发布时间】:2013-04-11 14:56:31
【问题描述】:

我使用的是 Win8 VC++2012。

上面的代码是为了说明子类B在任何情况下都不能访问A::a。我也不能更改 A::a 但 A::b 和 A::c 的访问属性。

所以A::c并没有从A继承到B。但是sizeof(A)和sizeof(B)分别是12和24,也就是说A::a DO占用了B中的内存。

  1. B 怎么可能将 A::a 存储在它的内存中而永远无法访问它?
  2. C++ Primer 一书说,我们可以恢复基类成员的访问属性,但不能改变它。这里我的代码显示我可以在 B 中将 A::b 的访问属性从受保护更改为公开。为什么?

代码如下:

#include <iostream>
using namespace std;

class A
{
private:
    int a;
protected:
    int b;
public:
    int c;

    A(int a, int b, int c): a(a), b(b), c(c)
    {
        cout << "A: ";
        cout << a << " ";
        cout << b << " ";
        cout << c << endl;
    }
};

class B: protected A
{
private:
    int d;
protected:
    int e;
    //using A::a; COMPILE ERROR
public:
    int f;
    //A::a;  COMPILE ERROR
    using A::c; //RESTORE A::c public access
    A::b; // change A::b from protected to public

    B(int d, int e, int f): A(d, e, f), d(d), e(e), f(f)
    {
        cout << "B\n";
        //cout << a << endl; COMPILE ERROR
        cout << b << " ";
        cout << c << " ";
        cout << d << " ";
        cout << e << " ";
        cout << f << endl;
    }
};
int main()
{
    A a(1,2,3);
    B b(4,5,6);

    cout << "sizeof(A)=" << sizeof(A) << endl; //OUTPUT 12
    cout << "sizeof(B)=" << sizeof(B) << endl; //OUTPUT 24
    return 0;
}

【问题讨论】:

  • 不要相信sizeof 会按您的预期工作。
  • 另外,你期待什么? privateprivate

标签: c++ inheritance private


【解决方案1】:

子级继承父级的私有成员,但不能访问它们。访问让他们protected

class A
{
protected: // <<------------ make `a` as protected in parent
    int a;

【讨论】:

  • 正如我的代码所示,私有成员 A::a 不能在子类中进行保护。
  • 看,我改变了父类,而不是子类。
【解决方案2】:

当您使用继承时,您将创建一个基类的实例以及一个派生类的实例。基类内部的所有成员都是在您实例化派生类时构造的,即使派生类无法访问它们。

如果您需要成员在基类中是私有的,但您仍想在派生类中访问它。在基类中创建一个受保护的访问器,让您可以访问私有成员。

 protected:    
 int &geta() { return a; }

【讨论】:

    【解决方案3】:

    所以 A::c 不是从 A 继承到 B

    你是说

    所以 A::a 不是从 A 继承到 B

    但即便如此,它确实是继承的。它只是不能直接访问。但是B 仍然会有a

    为什么这是必要的?因为您可以在A 中拥有公共方法,这些方法可以设置或获取a 的值。这些函数可以让B 间接访问它自己的a

    例如

    class A {
    private:
        int a;      // a is private
    public:
        void set_a(int i) {a = i;}
    };
    
    class B : protected A {
    public:
        using A::set_a;   // we bring set_a to public access
    };
    
    int main() {
        B b;
        b.set_a(2);   // change b.a indirectly
        b.a = 2;      // Error
    }
    

    【讨论】:

    • A::c 当然是从 A 继承到 B。它是 A 的公共成员。
    • @Zachery 你,但那是你写的:)
    • @Zachery 和继承不依赖于可见性。 一切都继承自 A。唯一不同的是可见度级别。
    【解决方案4】:

    我不明白问题是什么:

    B 是 A,这就是为什么即使 B 无法访问它,a 属性也会占用一些空间。

    如果有一个公共方法geta()返回a,如果a不在B中,它怎么会返回a?

    【讨论】:

      猜你喜欢
      • 2018-06-14
      • 2013-02-12
      • 2017-04-14
      • 2013-08-30
      • 2020-09-01
      • 2014-09-20
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      相关资源
      最近更新 更多