C++:访问祖父方法

Posted

技术标签:

【中文标题】C++:访问祖父方法【英文标题】:C++: Accessing Grandparent Method 【发布时间】:2011-06-09 19:44:12 【问题描述】:

为什么这不起作用,什么是好的选择?

class Grandparent

    void DoSomething( int number );
;

class Parent : Grandparent

;

class Child : Parent

    void DoSomething()
    
        Grandparent::DoSomething( 10 ); // Does not work.
        Parent::DoSomething( 10 ); // Does not work.
    
;

【问题讨论】:

【参考方案1】:
class Grandparent

protected:
    void DoSomething( int number );
;

class Parent : protected Grandparent

;

class Child : Parent

    void DoSomething()
    
        Grandparent::DoSomething( 10 ); //Now it works
        Parent::DoSomething( 10 ); // Now it works.
    
;

至少它需要看起来像这样。在使用类时,默认情况下事物是私有的,这包括来自子类。

http://codepad.org/xRhc5ig4

有一个完整的例子可以编译和运行。

【讨论】:

请注意struct 的成员默认是公开的。事实上,classstruct 之间的唯一区别是class 成员默认为私有,struct 成员默认为公开。 是的,我刚刚修复了 OP,我刚刚编译了我的示例并且它可以工作......我需要查看我在实际代码中做错了什么。谢谢。 您是否遇到编译错误?还是在运行时出现问题? @Joshua 我刚刚用 GCC 编译了你的示例。我收到以下错误: temp3.cpp:(.text._ZN5Child11DoSomethingEv[Child::DoSomething()]+0x19): undefined reference to Grandparent::DoSomething(int)' temp3.cpp:(.text._ZN5Child11DoSomethingEv[Child::DoSomething()]+0x2a): undefined reference to Grandparent::DoSomething(int)' 为了记录,面向对象中继承的一般概念通常在C++中实现为public继承。我建议初学者始终使用class Subclass : public Superclass【参考方案2】:

我猜你的代码没有编译 - 错误的主要来源是缺少方法 Child::DoSomething() 的返回类型说明符。

【讨论】:

不,这不是问题所在。我只是不小心在示例中遗漏了它。 @Jay 好的,我一开始就看到了。下一个错误来源是公共继承在子类中隐藏了父类的私有成员,因此您需要提升父类中的访问级别 - 正如 Joshua 的回答中所述 你不是说私有继承吗? @Joshua:哎呀,我忽略了这一点 - 这就是你提升和继承级别的原因【参考方案3】:
class Grandparent

    public:
    void DoSomething( int number )
        cout<<number;
    
;

class Parent : public Grandparent

    public:
    void DoSomething(int x)
        cout<<x<<'\n';
    
;

class Child : public Parent

    public:
    void DoSomething()
    
        Grandparent::DoSomething( 10 ); // works.
        Parent::DoSomething( 10 ); // works.
    
;

C++ 中的默认继承类型是私有的,C++ 中的默认成员函数访问说明符也是私有的。因此,在任何情况下都不能访问 GrandParent 类的私有成员。您已将 GrandParent 的 DoSomething() 设为公开或受保护。然后提及适当的继承类型。

【讨论】:

【参考方案4】:

(1) 是的,当我们使用 public 或 protected 访问修饰符继承派生类时,我们只能访问派生类中的祖父母成员。

(2) 声明为受保护的基类成员在类外不可访问,但该类的任何派生类都可以访问它们。当您通过 public 或 protected 访问修饰符继承基类的受保护成员时,该数据成员访问说明符在派生类中受到保护。

(3) 默认情况下,访问修饰符在 C++ 中的继承中是私有的,在您给定的示例中。由于您试图访问子类中基类的私有成员,因此必然会产生编译时错误。也请阅读下一点。

(4) 声明为私有的基类成员当然继承到派生类。但是,无论继承时使用何种访问修饰符,它们都不可访问。这是可用性与可访问性的问题。基类的私有成员可供后续派生类使用,但不可访问。我们可以在私有继承基类之后使用 sizeof(derived class object) 运算符来检查。

让我们讨论另一件事。我们如何访问基类的私有成员? 好吧,我们可以通过使用友元函数和指针来做到这一点。但是,在基类中声明 Friend 函数取决于该基类的创建者。所以,我们不会在这篇文章中讨论这个。

class Base

  private : 
           int x1,x2;
;

class Derived : public Base

     public : 
              int x3;
              void display(int *ptr)
              
                   cout << "the value of x1 = " << *(ptr) << endl;
                   cout << "the value of x2 = " << *(ptr+1) << endl;
                   cout << "the value of x3 = " << *(ptr+2) << endl;
              
;

int main()

    Derived d;
    int *ptr = (int *)&d.x3; // typecasting 

    *ptr = 3; // setting x3 as 3
     ptr--;
     
    *ptr = 2; // setting x2 as 2
     ptr--;
 
    *ptr = 1; // setting x1 as 1
     ptr--;

     d.display(ptr);
     return 0;

我们已经成功访问​​了基类的私有成员。

我想分享的还有一件事是:如果我们有一个虚拟祖父类,我们可以直接从子类调用祖父构造函数。但一般情况下是不允许直接调用祖父构造函数的,必须通过父类调用。只有在使用虚拟关键字时才允许。

【讨论】:

【参考方案5】:

它的多级继承尝试为您的祖父类提及访问说明符。

因为默认情况下访问说明符是 PRIVATE,我们将无法访问子类中父类的私有成员。

【讨论】:

以上是关于C++:访问祖父方法的主要内容,如果未能解决你的问题,请参考以下文章

一般继承 /虚方法 跳过父类执行 祖父类的方法

在 c++ 中的菱形问题中,为啥我们需要从子类中调用祖父构造函数?

如何避免在 C++ 中调用祖父构造函数?

防止孙子调用其祖父母的方法

objc从外面打电话给祖父母方法

JAVA的XX.put中的put方法,是在哪个父类或祖父类中,详述父类链。