是否可以在不实例化所述类的情况下调用派生类的虚函数?

时间:2017-10-26 04:22:07

标签: c++ virtual-functions

我有两个A和B类派生自抽象类Letter。在运行时,我想根据用户输入调用派生类之间不同的函数。 以下代码执行我想要的功能:

Letter.h:

#pragma once
#include <iostream>

class Letter
{
public:
    virtual void PrintAlphabetPosition() = 0;
    virtual ~Letter(){};
};

A.H:

#include "Letter.h"

class A : public Letter
{
public:
    virtual void PrintAlphabetPosition() { std::cout << "1" << std::endl; };
    virtual ~A(){};
};

B.h:

#include "Letter.h"

class B : public Letter
{
public:
    virtual void PrintAlphabetPosition() { std::cout << "2" << std::endl; };
    virtual ~B(){};
};

main.cpp中:

#include <iostream>
#include "Letter.h"
#include "A.h"
#include "B.h"

void main() {
    Letter* letter;
    char input;
    std::cin >> input;
    if (input == 'A') {
        letter = new A();
    } else {
        // Default to B
        letter = new B();
    }
    letter->PrintAlphabetPosition(); // Prints 1 or 2 as expected

    delete letter;
}

我的问题是,有没有办法在main.cpp中执行功能而无需实例化A或B(甚至不是单例)?我将在这两个类中拥有的每个函数都不会依赖于类的特定实例。

我考虑过将A和B变为静态&#39;类通过将所有成员函数和变量声明为静态,然后将构造函数隐藏为私有,类似于此问题的答案:How do you create a static class in C++?。但是,静态声明会与虚拟声明冲突。

我还试图通过将PrintAlphabetPosition()声明为纯虚函数并将实现移动到各自的.cpp文件中来将A和B转换为抽象类。但是,我怎么能在运行时动态地选择A :: PrintAlphabetPosition()和B :: PrintAlphabetPosition()?

编辑:为了清楚起见,我应该提一下,A类和B类充当以不同方式实现Letter的实用程序类,并且它们具有更多功能。此外,我希望使用更多的派生类别(不仅仅是A和B)。

2 个答案:

答案 0 :(得分:1)

virtual函数无法满足您的需求,因为这些函数本身就需要一个实例。

你可以做的是有一个std::function变量,它是从类AB s`静态函数初始化的:

class A {
public:
     static void PrintAlphabetPosition();
};

class B {
public:
     static void PrintAlphabetPosition();
};

void main() {
    std::function<void()> letterFn;
    char input;
    std::cin >> input;
    if (input == 'A') {
        letterFn = A::PrintAlphabetPosition;
    } else {
        // Default to B
        letterFn = B::PrintAlphabetPosition;
    }
    letterFn(); // Prints 1 or 2 as expected
}

答案 1 :(得分:0)

如果函数不需要引用特定对象(如果你想在不实例化的情况下调用它就必须为true),你应该能够将它重写为静态方法。然后,您可以拨打A::PrintAlphabetPosition()B::PrintAlphabetPosition()来拨打您想要的电话。

如果您还想要一个虚方法,您也可以添加它,并让它调用特定于类的静态方法。我认为你需要为虚拟和静态方法使用不同的名称。