首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >虚函数是在C++中实现运行时多态的唯一方法吗?

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

Stack Overflow用户
提问于 2013-02-19 16:46:46
回答 6查看 16.9K关注 0票数 9

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

他说:“不,只有使用虚拟函数才能实现。”

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

代码语言:javascript
运行
复制
#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;
}

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

我的问题如下:

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

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

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

代码语言:javascript
运行
复制
void func2(A& myA)
{
    cout << myA.i << endl;
    // dynamic/static cast myA to myB
    cout<<myB.j << endl;
}

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

EN

回答 6

Stack Overflow用户

发布于 2013-02-19 16:51:14

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

这个例子是动态多态性的例子。

您需要在基类中提供一个virtual成员函数,并在派生类中重写它。要调用的实际方法由基类指针所指向的对象的实际类型决定。

代码语言:javascript
运行
复制
#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;
}

输出:

代码语言:javascript
运行
复制
In B::doSomething()
In A::doSomething()

只有通过虚拟函数才能获得运行时多态性

不是,但是virtual函数是最常见也是最正确的方法。

多态性可以通过函数指针来实现。考虑以下,实际要调用的方法是在运行时根据用户输入决定的。它是多态的一种形式,不是严格意义上的C++,它要求不同的类型有不同的行为。

代码语言:javascript
运行
复制
#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;
}

上面的例子有运行时多态性还是编译时?

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

票数 9
EN

Stack Overflow用户

发布于 2013-02-19 17:01:21

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

您可以向它传递各种句柄,它可以打印到文件、标准输出、打印机、a socket,以及系统可以表示为流的任何内容。

代码语言:javascript
运行
复制
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");
票数 6
EN

Stack Overflow用户

发布于 2013-02-19 16:57:43

你写的不是多态性。

下面是在C++中实现多态性的方法:

代码语言:javascript
运行
复制
#include<iostream>
using namespace std;

class A
{
public:
    virtual void func(){
        cout << "printing A" << endl;
    }

    virtual ~A(){}
};

class B : public A
{
public:
    void func(){
        cout << "printing B" << endl;
    }
};

int main()
{
    A* a = new A();
    A* b = new B();

    a->func(); // "printing A"
    b->func(); // "printing B"

    delete a;
    delete b;

    return 0;
}

如果要删除虚拟关键字,A的方法func将被调用两次。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14953222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档