像Delphi一样覆盖C/C++中的方法

Rod*_*ino 2 c++ delphi

在Delphi中,我们可以选择这样做:

TClass1 = class
  procedure Test; virtual;
end;

TClass2 = class(TClass1)
  procedure Test; override;
end;
Run Code Online (Sandbox Code Playgroud)

所以在代码中,如果我创建一个TClass2的实例,即使我将对象转换为:

TClass1(ObjectClass2).Test;
Run Code Online (Sandbox Code Playgroud)

应用程序将调用在TClass2上声明的函数.

但是在C/C++中我找不到办法做到这一点.

如果我将一些void声明为virtual并在我对子类执行转换时在子类中实现相同的void,则它将不使用children类的实现.

有谁知道如何在C/C++中重现Delphi的行为?


新信息:这些是我的文件.

---------------------- File Filho.hpp
#ifndef FILHO_HPP
#define FILHO_HPP
#include "Pai.hpp"

class Filho : public Pai {
public:
    Filho();
    virtual ~Filho();
    void metodoX();
};

Filho::Filho() {}
Filho::~Filho() {}

void Filho::metodoX() {
    std::cout << "Hello Filho!" << std::endl;
}
#endif


---------------------- File Pai.hpp
#ifndef PAI_HPP
#define PAI_HPP
#include <iostream>

class Pai {
public:
    Pai();
    virtual ~Pai();
    virtual void metodoX();
};
Pai::Pai() {}
Pai::~Pai() {}

void Pai::metodoX() {
    std::cout << "Hello Pai!" << std::endl;
}

#endif

---------------------- File Main.hpp
#include "Pai.hpp"
#include "Filho.hpp"

int main() {
    Pai pai;
    pai.metodoX();      //Here output the msg Hello Pai!

    Filho filho;           
    filho.metodoX();    //Here output the msg Hello Filho!

    ((Pai) filho).metodoX(); //Here output the msg Hello Pai! , but here if I use the directive 'override' in Delphi, the output will be Hello Filho!. Here is my doubt.
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

wkl*_*wkl 8

我不是Delphi专家,但我可以解释这些东西在C++中的表现.

因此在C++中,您可以拥有一个定义virtual函数的类,这意味着如果您使用基类指针/对象的引用,则可以通过动态调度(即运行时函数查找)调用该函数.

#include <iostream>

class BaseClass
{
public:
    virtual void virtFunc() { std::cout << "BaseClass\n"; } // notice the 'virtual' keyword
    void nonvirtFunc() { std::cout << "BaseClass\n"; }
};


class SubClass : public BaseClass
{
public:
   virtual void virtFunc() { std::cout << "SubClass\n"; }
   void nonvirtFunc() { std::cout << "SubClass\n"; }
};

int main()
{
    // You need to use base class pointers/references
    SubClass sc = SubClass();
    BaseClass *bcp = &sc;
    bcp->virtFunc(); // prints "SubClass"     
    bcp->nonvirtFunc(); // prints "BaseClass"   

    // doing it by allocating an object on heap
    BaseClass *dbcp = new SubClass();
    dbcp->virtFunc(); // prints "SubClass"
    dbcp->nonvirtFunc(); // prints "BaseClass"
    delete dbcp; // in a real program, you should have a virtual destructor which will be called from this code

    BaseClass bc = SubClass();
    bc.virtFunc(); // prints "BaseClass", and in more complex objects, slicing occurs
}
Run Code Online (Sandbox Code Playgroud)

您发布的新代码

我看到你用你的代码更新了这个:

((Pai)filho).metodoX();
Run Code Online (Sandbox Code Playgroud)

因此,当您这样做时,您不使用指向基类的指针/引用.您只是将filho对象转换为Pai对象.这不会导致多态函数调用,而只会调用该Pai::metodoX()函数.

如果你这样做了:

((Pai*)filho)->metodoX();
Run Code Online (Sandbox Code Playgroud)

它会叫FilhometodoX()多态.


Dav*_*nan 6

在C++中你会写:

class Class1
{
  public:
    virtual void Test();
};

class Class2: public Class1
{
  public:
    virtual void Test();
};

Class1* obj = new Class2();
obj->Test();//calls Class2.Test()
Run Code Online (Sandbox Code Playgroud)

这与Delphi示例相同.

关键是在堆上创建C++对象并维护对它的引用,这当然是Delphi中不支持基于堆栈的对象的唯一方法.