虚函数段错误

virtual functions segmentation fault

我想学习虚函数。我在 class Base 虚拟化了 print() 并且我的程序崩溃了。为什么我必须用 new 创建两个对象?

#include <iostream>

class Base {
    public:
        virtual void print();
};

void Base::print() {
    std::cout << "Base print method" << std::endl;
}

class Derived : public Base {
    public:
        void print();
};

void Derived::print() {
    std::cout << "Derived print method" << std::endl;
}

int main()
{
    Base* b; // Base* b = new Base(); runs
    b->print();
    Derived* d; // Derived *d = new Derived(); runs
    d->print();
}

因为 Base* b 不会创建对象,只要您不通过添加 new Base() 告诉它这样做。因此取消引用指向 print 函数的指针没有有效目标。

Base* b; 不创建对象,而是创建一个 Base* 类型的指针,具有 自动存储持续时间 。取消引用该指针的行为未定义。

Base bnew Base() 实际创建对象。前者自动存储时长,后者动态存储时长

您正在使用指针,因此它们需要指向某物。

你基本上是在说:“嘿,这个 b 变量指向一个 Base 对象”,但是你从来没有创建一个基础对象(使用 new),所以它指向随机内存,当您尝试将该内存视为 Base 对象时崩溃。

Why do I have to create the two objects with new?

你不必。

为了多态需要动态创建对象是一个常见的误解。多态性通常与动态创建的对象一起使用,但启用多态性并不是绝对必要的。您需要多态性的引用或指针,因此例如这将起作用:

#include <iostream>

class Base {
    public:
        virtual void print();
};

void Base::print() {
    std::cout << "Base print method" << std::endl;
}

class Derived : public Base {
    public:
        void print();
};

void Derived::print() {
    std::cout << "Derived print method" << std::endl;
}

void do_print(Base& b) {
   b.print();
}    

int main()
{
    Base b;
    do_print(b);
    Derived d;
    do_print(d);
}

在您的代码中,您只有 main 中的指针,但您从不创建对象。你的指针不指向对象,它们是未初始化的。取消引用这些指针会调用未定义的行为。