Foo
和Bar
类:压倒一切。在Java中,存在super.funcname()
语法。在C ++中可能吗?#1 楼
C ++语法如下:class Bar : public Foo {
// ...
void printStuff() {
Foo::printStuff(); // calls base class' function
}
};
评论
这样做有任何可能的问题吗?这是不好的做法吗?
–Robben_Ford_Fan_boy
11年2月2日在15:01
@David:不,这样做是完全正常的,尽管如果它真的有用的话可能取决于您的实际班级。仅在需要执行某些操作时才调用基类方法;)。
– sth
2011年2月2日在15:13
注意,当您的客户需要这样做时,这是一种代码气味! (称为“通话超级要求”,请在此处查看:en.wikipedia.org/wiki/Call_super)
–v.oddou
2014年3月28日在3:49
@ v.oddou:在有用的情况下调用超类没有什么错。您链接的页面只是有关继承的一些特定潜在问题。它甚至自己说,一般而言,调用超类没有什么错:“请注意,调用父类是反模式,这是必需的。在真实代码中有很多示例,子类中的方法可能仍然想要超类的功能,通常只在其中增加父功能。”
– sth
2014年3月28日在11:49
这对于大多数人来说可能是显而易见的,但是为了完整起见,请记住不要在构造函数和析构函数中这样做。
–TigerCoding
14年7月6日在22:23
#2 楼
是的,class Bar : public Foo
{
...
void printStuff()
{
Foo::printStuff();
}
};
它与Java中的
super
相同,除了它允许您在具有多个继承时从不同的基础调用实现。 class Foo {
public:
virtual void foo() {
...
}
};
class Baz {
public:
virtual void foo() {
...
}
};
class Bar : public Foo, public Baz {
public:
virtual void foo() {
// Choose one, or even call both if you need to.
Foo::foo();
Baz::foo();
}
};
评论
这是比所选答案更好的答案。谢谢。
–疯狂物理学家
14-10-17在20:41
多重继承?噢!
–拉米诺
18年7月23日在16:14
#3 楼
有时,当您不在派生函数中时,需要调用基类的实现...它仍然可以工作:评论
请注意,您需要x都属于Base *类型,并且需要使用Base :: Foo语法才能使其工作
– TTimo
18年3月21日在19:59
#4 楼
万一您为类中的许多功能执行了以下操作:评论
做到这一点很有趣,但不能与多重继承一起使用。
–疯狂物理学家
14-10-17在20:43
如果您有超过1个基类怎么办?无论如何,试图弯曲C ++使其看起来像其他语言是愚蠢的,而且通常是徒劳的。只要记住基地的名字,然后用它来称呼它即可。
– underscore_d
16年4月11日在13:18
#5 楼
如果要从其派生类中调用基类的函数,则只需在覆盖的函数中调用并提及基类名称(例如Foo :: printStuff())。代码在这里再次,您可以在运行时使用该类的对象(派生或基类)确定要调用哪个函数。但这要求您在基类上的函数必须标记为virtual 。
下面的代码
#include <iostream>
using namespace std;
class Foo
{
public:
int x;
virtual void printStuff()
{
cout<<"Base Foo printStuff called"<<endl;
}
};
class Bar : public Foo
{
public:
int y;
void printStuff()
{
cout<<"derived Bar printStuff called"<<endl;
Foo::printStuff();/////also called the base class method
}
};
int main()
{
Bar *b=new Bar;
b->printStuff();
}
#6 楼
如果存在多个继承级别,则即使实际实现在较低级别,也可以指定直接基类。class Foo
{
public:
virtual void DoStuff ()
{
}
};
class Bar : public Foo
{
};
class Baz : public Bar
{
public:
void DoStuff ()
{
Bar::DoStuff() ;
}
};
在此示例中,Baz类指定Bar :: DoStuff()尽管Bar类不包含DoStuff的实现。这是一个细节,Baz不需要知道。
最好使用Bar :: DoStuff而不是Foo :: DoStuff来调用Bar :: DoStuff,以防Bar的更高版本也覆盖此方法。 >
#7 楼
检查此...#include <stdio.h>
class Base {
public:
virtual void gogo(int a) { printf(" Base :: gogo (int) \n"); };
virtual void gogo1(int a) { printf(" Base :: gogo1 (int) \n"); };
void gogo2(int a) { printf(" Base :: gogo2 (int) \n"); };
void gogo3(int a) { printf(" Base :: gogo3 (int) \n"); };
};
class Derived : protected Base {
public:
virtual void gogo(int a) { printf(" Derived :: gogo (int) \n"); };
void gogo1(int a) { printf(" Derived :: gogo1 (int) \n"); };
virtual void gogo2(int a) { printf(" Derived :: gogo2 (int) \n"); };
void gogo3(int a) { printf(" Derived :: gogo3 (int) \n"); };
};
int main() {
std::cout << "Derived" << std::endl;
auto obj = new Derived ;
obj->gogo(7);
obj->gogo1(7);
obj->gogo2(7);
obj->gogo3(7);
std::cout << "Base" << std::endl;
auto base = (Base*)obj;
base->gogo(7);
base->gogo1(7);
base->gogo2(7);
base->gogo3(7);
std::string s;
std::cout << "press any key to exit" << std::endl;
std::cin >> s;
return 0;
}
输出
Derived
Derived :: gogo (int)
Derived :: gogo1 (int)
Derived :: gogo2 (int)
Derived :: gogo3 (int)
Base
Derived :: gogo (int)
Derived :: gogo1 (int)
Base :: gogo2 (int)
Base :: gogo3 (int)
press any key to exit
最好的方法是使用base :: function如@sth
评论
如本问题所述,由于受保护的继承,该方法不起作用。要强制转换基类指针,您必须使用公共继承。
–黑暗产品
20年6月3日,9:06
有趣。阅读完此答案后,我认为在继承受保护的情况下,派生自Base的事实仅对类本身可见,而对外部也不可见。
–黑暗产品
20年6月12日在10:40
#8 楼
是的,您可以调用它。在子类中调用父类函数的C ++语法为class child: public parent {
// ...
void methodName() {
parent::methodName(); // calls Parent class' function
}
};
了解有关函数重写的更多信息。
评论
来自基类的虚函数调用的可能重复项对于Google员工:请注意,您可能会遇到类似将其存储为不是指针的类成员变量的问题。在这里查看我的答案:stackoverflow.com/questions/4798966/…我参与了new / delete的修复。