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

Is it possible to call a virtual function of a derived class without instantiating said class?

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

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;
}

我的问题是,有没有一种方法可以在不实例化 A 或 B(甚至不是单例)的情况下执行 main.cpp 中的功能?我将在这两个 class 中拥有的每个函数都永远不会依赖于 class.

的特定实例

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

我还尝试通过将 PrintAlphabetPosition() 也声明为纯虚函数并将实现移动到它们各自的 .cpp 文件中来将 A 和 B 变成抽象 classes。但是,我将如何在运行时动态地在 A::PrintAlphabetPosition() 和 B::PrintAlphabetPosition() 之间进行选择?

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

virtual 函数无法满足您的需求,因为它们本质上需要一个实例。

你可以做的是有一个 std::function 变量,它是从 class As 或 Bs `static 函数初始化的:

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
}

如果函数不需要引用特定对象(如果您希望能够在不实例化任何东西的情况下调用它,则必须为真),您应该能够将其重写为静态方法。然后您可以调用 A::PrintAlphabetPosition()B::PrintAlphabetPosition() 来调用您想要的那个。

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