繁体   English   中英

那么,为什么我必须在基类中定义虚函数?

[英]So, why do I have to define virtual function in a base class?

我正在尝试创建一个简单的基本抽象类,其中包含一个虚函数和一个定义该虚函数的子类。 在编译期间运行以下会产生错误:

#include <iostream>
using namespace std;

class Animal {
public:
    virtual void speak();

};

class Cat : public Animal{
public:
    void speak() override {
        cout << "Meow!";
    }
};

int main() {
    Cat cat;
    Animal* base = &cat;
    base->speak();
}
// error LNK2001: unresolved external symbol "public: virtual void __thiscall Base::speak(void)" (?speak@Base@@UAEXXZ)

我的 IDE 建议在 Animal 中为 speak() 添加一个无用的定义,它可以工作:

#include <iostream>
using namespace std;

class Animal {
public:
    virtual void speak();
};

void Animal::speak() {

}

class Cat : public Animal{
public:
    void speak() override {
        cout << "Meow!";
    }
};

int main() {
    Cat cat;
    Animal* base = &cat;
    base->speak();
}

那么,为什么我必须在基类中定义虚函数?

相比之下,在 Java 中没有这样的需要,甚至没有这种可能性(这更有意义):

abstract class Animal {
    abstract void speak();
}

class Cat extends Animal {
    void speak() {
        System.out.println("Meow!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.speak();
    }
}

是的,应该定义非纯虚函数。

[class.virtual]/12

在类中声明的虚函数应在该类中定义或声明为纯( [class.abstract] ),或两者兼而有之; 不需要诊断( [basic.def.odr] )。

您可以提供定义,或将其标记为纯虚拟。

class Animal {
public:
    virtual void speak() = 0;
};

您需要在基类中使用= 0将其标记为“抽象”(或 C++ 术语中的“纯虚拟”)。

class Animal {
public:
    virtual void speak() = 0;
};

在 C++ 中,如果一个类至少有一个纯虚函数,那么它就是抽象的。

这节课

class Animal {
public:
    virtual void speak();

};

不是抽象类,因为类中没有声明纯虚函数。

通过在类定义的函数声明中使用纯说明符来指定虚函数。

那是为了使类抽象,你应该像这样声明它的虚函数

class Animal {
public:
    virtual void speak() = 0;

};

编译器需要构建一个指向虚函数的指针表,其中将存储虚函数的实际地址。 如果链接器无法解析虚拟函数的地址,则会发出错误消息。

请记住,可以定义纯虚函数。 例如你可以写

class Animal {
public:
    virtual void speak() = 0;

};

void Animal::speak()
{
    std::cout << "The animal has issued a sound.\n";
}

在派生类中,您可以通过以下方式定义函数

class Cat : public Animal{
public:
    void speak() override {
        Animal::speak();
        cout << "Meow!";
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM