基类可以声明一个虚拟方法但不能定义它吗?仍在派生类中定义

问题描述 投票:0回答:2
#include <vector>

class M {
    public:
        M(unsigned int);
        unsigned int n;
};

M::M(unsigned int i) { n = i; }

class A {
    protected:
        char t;
    public:
        virtual ~A();
        virtual std::vector<M> foo(unsigned int);
        char getChar();
};

A::~A(){}
std::vector<M> A::foo(unsigned int u) {
    std::vector<M> v;
    return v;
}
char A::getChar() { return t; }

class B : public A {
    public:
        B();
        std::vector<M> foo(unsigned int);
};

B::B() { t = 'b'; }
std::vector<M> B::foo(unsigned int c) {
    std::vector<M> v;
    for (unsigned int i = 0; i < c; i++) {
        v.push_back(i);
    }
    return v;
}

int main() {}

在上面的代码中,我在unused parameter 'u'中收到警告A::foo()。但是,完全删除该函数后,我收到一个错误,即A::foo()中存在对B的未定义引用。 B正在实现虚拟方法,并且无法在A中找到对定义的引用,但是如果期望的行为是派生类,则为什么需要在A中定义它,所以总是会覆盖基类,否则话说,A::foo()永远不会被调用吗?

为了更具说明性,是否有一种方法可以在基类中声明虚拟方法,而仅在派生类中对其进行定义?考虑到基本方法调用永远不会显式发生。

c++ abstract-class virtual c++03
2个回答
1
投票

您正在寻找的被称为“纯虚函数”,您可以在带有= 0的类定义中声明它:

class A {
    protected:
        char t;
    public:
        virtual ~A();
        virtual std::vector<M> foo(unsigned int) = 0; // <--
        char getChar();
};

您可以阅读有关纯虚函数及其效果的更多信息at cppreference.com


1
投票

不是必须在基类中使用关键字“ virtual”,它只是清楚地表明这是一个由派生类开始重写的函数,这是故事的道理:您需要将virtual关键字添加到派生类函数中。

PS:抽象类是具有至少一个纯虚函数的类,也就是抽象类从未使用过的函数,只有派生类才使用。您还需要将函数分配为0才能使其抽象。

在B类中:虚拟std :: vector B :: foo(unsigned int c)

在A类中:虚拟std :: vector foo(unsigned int)= 0;

© www.soinside.com 2019 - 2024. All rights reserved.