虚函数是在C++中实现运行时多态的唯一方法吗?

Ash*_*rma 9 c++ polymorphism

我的一个朋友问我"如何在C++中实现运行时多态性?" 我回答"通过继承"

他说:"不,只能使用虚拟功能才能实现".

所以我给了他一个以下代码的例子: -

#include<iostream>
using namespace std;

class A
{
public:
    int i;
    A(){i=100;}
};

class B : public A
{
public:
    int j;
    B(){i = -1; j = 99;}
};

void func(A& myA)
{
    cout<<myA.i << endl;
}

int main()
{
    B b;
    A* a = new B();
    func(*a);
    func(b);
    delete a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这里,函数func()接受A的引用,但是我们传递B的对象,我们可以打印公共成员"i"的值.他说这是编译时多态.

我的问题是: -

1)运行时多态性是否仅通过虚函数实现?

2)上面的例子是运行时多态还是编译时间?

3)如果我有以下代码: -

void func2(A& myA)
{
    cout << myA.i << endl;
    // dynamic/static cast myA to myB
    cout<<myB.j << endl;
}
Run Code Online (Sandbox Code Playgroud)

它是什么样的多态性?或者甚至是多态?

Alo*_*ave 9

该示例未显示动态多态性.要调用的方法在编译时是已知的.关于应该调用哪个方法,没有运行时决定(基于实际对象类型).不同类型没有不同的行为.

例如,动态多态性的例子.
您需要virtual在Base类中提供成员函数,并在派生类中覆盖它.要调用的实际方法由Base类指针指向的对象的实际类型决定.

在线样本:

#include<iostream>
using namespace std;

class A
{
public:
    virtual void doSomething()
    {
        std::cout<<"\nIn A::doSomething()";
    }
};

class B : public A
{
public:
    virtual void doSomething()
    {
        std::cout<<"\nIn B::doSomething()";
    }
};



int main()
{
    B b;
    A obj;
    A* a = &b;
    a->doSomething();

    a = &obj;
    a->doSomething();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

In B::doSomething()
In A::doSomething()
Run Code Online (Sandbox Code Playgroud)

运行时多态性是仅通过虚拟函数实现的吗?

不,但virtual功能是最常见和最正确的方法.
多态性可以通过函数指针实现.请考虑以下代码示例,实际调用方法取决于用户输入在运行时决定.它是一种多态性,不是严格意义上的C++意义,它规定了不同类型的不同行为.

#include <iostream>

typedef void (*someFunction)(int, char*);

void FirstsomeFunction(int i, char *c)
{
    std::cout<<"\n In FirstsomeFunction";
}

void SecondsomeFunction(int i, char *c)
{
    std::cout<<"\n In SecondsomeFunction";
}

int main()
{
    someFunction arr[1];
    int x = 0;
    std::cin >> x;

    if(x ==0)
        arr[0] = &FirstsomeFunction;
    else
        arr[0] = &SecondsomeFunction;

    (arr[0])(10,"Hello");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

以上示例是否具有运行时多态性或编译时间?

没有任何类型的多态性.在所有情况下都会调用相同的方法.对于不同类型没有不同的行为,因此它不会被分类为任何类型的多态.

  • "*运行时多态性是仅通过虚拟功能实现的吗?*是的." 我认为答案应该是否定的.简单的函数指针也可用于实现运行时多态性. (4认同)
  • 我认为这是一个很好的答案,但是你的答案是*运行时多态性只能用虚拟函数实现吗?*会误导你说不,但是作为理由,通过CRTP提出静态多态性,这只是远程相关的.听起来像政治家回答...... (4认同)
  • @CodeClown:是的,它仍然是多态的.方法上的`override`关键字指定该函数必须覆盖基类方法,因此必须匹配被覆盖的函数的类型.调用的方法仍然取决于被指向对象的实际类型. (2认同)

Pet*_*ood 5

C语言的fprintf是一个多态函数.

您可以传递各种句柄,它可以打印到文件,标准输出,打印机,套接字,系统可以表示为流的任何内容.

FILE* file = fopen("output.txt", "w");                    // a file
FILE* file = stdout;                                      // standard output
FILE* file = fopen("/dev/usb/lp0", "w");                  // a usb printer
FILE* file = popen("/usr/bin/lpr -P PDF", "w");           // a PDF file
FILE* file = fdopen(socket(AF_INET,SOCK_STREAM,0), "r+"); // network socket

fprintf(file, "Hello World.\n");
Run Code Online (Sandbox Code Playgroud)