假设我有如下设置的FooBar类:压倒一切。在Java中,存在super.funcname()语法。在C ++中可能吗?

评论

来自基类的虚函数调用的可能重复项

对于Google员工:请注意,您可能会遇到类似将其存储为不是指针的类成员变量的问题。在这里查看我的答案:stackoverflow.com/questions/4798966/…我参与了new / delete的修复。

#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
  }
};


了解有关函数重写的更多信息。