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
的成员默认是公开的。事实上,class
和struct
之间的唯一区别是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++:访问祖父方法的主要内容,如果未能解决你的问题,请参考以下文章