当前位置:  开发笔记 > 编程语言 > 正文

如何从派生类函数调用父类函数?

如何解决《如何从派生类函数调用父类函数?》经验,为你挑选了5个好方法。

如何使用C++从派生类调用父函数?例如,我有一个名为的类parent,以及一个child从父派生的类.每个班级都有一个print功能.在孩子的打印功能的定义中,我想调用父母的打印功能.我该怎么做呢?



1> Motti..:

我会冒这个明显的风险:你调用函数,如果它在基类中定义,它在派生类中自动可用(除非它是private).

如果派生类中存在具有相同签名的函数,则可以通过添加基类的名称后跟两个冒号来消除歧义base_class::foo(...).你应该注意到,不像Java和C#,C++并没有对"基础类"(关键字superbase),因为C++支持多重继承,这可能导致歧义.

class left {
public:
    void foo();
};

class right {
public:
    void foo();
};

class bottom : public left, public right {
public:
    void foo()
    {
        //base::foo();// ambiguous
        left::foo();
        right::foo();

        // and when foo() is not called for 'this':
        bottom b;
        b.left::foo();  // calls b.foo() from 'left'
        b.right::foo();  // call b.foo() from 'right'
    }
};

顺便说一下,你不能两次直接从同一个类派生,因为没有办法引用其中一个基类.

class bottom : public left, public left { // Illegal
};


@Mathai这就是为什么你不应该使用`using namespace std`.
@bluesm:在经典的OOP中它没有多大意义,但在泛型编程中`template class C:public A,public B {};`可以出现两种类型相同的原因取决于如何你的代码被使用(这使得A和B是相同的),可能是两个或三个抽象层的方式来自不知道你做了什么的人.
你为什么要两次从同一个班级继承?
我认为添加它会很有用,即使它没有直接在父类中实现,它也会调用父类方法,但**是在继承链的一个父类中实现的.
在旁注中,当我试图把它放在一个cpp文件中时,它让我很生气.我有'使用命名空间std'.'left'在该命名空间的某处定义.这个例子不会编译 - 让我疯狂:).然后我将'左'改为'左'.顺便说一句很棒的例子.
用来表示`你应该注意,与Java和C#不同,C++没有"基类"的关键字.
如果foo是两个基类中的虚函数,将会发生什么?

2> Greg Hewgill..:

给定父类命名Parent和子类命名Child,你可以这样做:

class Parent {
public:
    virtual void print(int x);
}

class Child : public Parent {
    void print(int x) override;
}

void Parent::print(int x) {
    // some default behavior
}

void Child::print(int x) {
    // use Parent's print method; implicitly passes 'this' to Parent::print
    Parent::print(x);
}

请注意,这Parent是类的实际名称而不是关键字.



3> Andrew Rolli..:

如果调用了您的基类Base,并且调用了您的函数,则FooBar()可以直接使用它来调用它Base::FooBar()

void Base::FooBar()
{
   printf("in Base\n");
}

void ChildOfBase::FooBar()
{
  Base::FooBar();
}



4> Andrey..:

在MSVC中,有一个Microsoft特定的关键字:__ super


MSDN:允许您明确声明您正在为要覆盖的函数调用基类实现.

// deriv_super.cpp
// compile with: /c
struct B1 {
   void mf(int) {}
};

struct B2 {
   void mf(short) {}

   void mf(char) {}
};

struct D : B1, B2 {
   void mf(short) {
      __super::mf(1);   // Calls B1::mf(int)
      __super::mf('s');   // Calls B2::mf(char)
   }
};


我不会试图证明`__super`的用法; 我在这里提到它作为另一种建议.开发人员应该了解他们的编译器并了解其功能的优缺点.
我不同意Andrey:如果我们考虑编写主要独立于编译器的软件而开发人员应该知道标准并且不需要打扰编译器功能,我认为这是一个好主意,因为大型项目迟早会出现多个编译器无论如何使用.
我宁愿不鼓励任何人使用它,因为它严重阻碍了代码的可移植性.
呃,我更喜欢`typdef`的父母像`super`.
*"开发人员应该知道他们的编译器"*这种推理,以及包含非标准功能,是导致IE6的原因......
如果函数也是虚拟的,这也适用.不错的提示.

5> Ajay yadav..:

如果基类成员函数的访问修饰符是受保护的或公共的,则可以从派生类中调用基类的成员函数。可以从派生成员函数调用基类的非虚拟成员和虚拟成员函数。请参考程序。

#include
using namespace std;

class Parent
{
  protected:
    virtual void fun(int i)
    {
      cout<<"Parent::fun functionality write here"<

输出:

$ g++ base_function_call_from_derived.cpp
$ ./a.out 
Child::fun partial functionality write here
Parent::fun functionality write here
Parent::fun3 functionality write here
Child::fun1 partial functionality write here
Parent::fun1 functionality write here

推荐阅读
臭小子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有