【问题标题】:virtual functions segmentation fault虚函数分段错误
【发布时间】:2020-09-30 08:14:14
【问题描述】:

我想学习虚函数。我在 Base 类中创建了 print() virtual 并且我的程序崩溃了。为什么我必须用 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();
}

【问题讨论】:

  • 未定义的行为!取消引用指针而不首先分配对象。
  • 你有一个指针b,但是它指向哪里?
  • 您的问题与虚函数无关。回顾对象指针和对象指针的区别
  • 创建一个指针并不会隐式地为该指针创建一个指向的对象。 Base *bDerived *d 创建两个未初始化的指针,并且不创建任何对象让它们指向。即使访问初始化指针的值也会产生未定义的行为,更不用说尝试取消引用它(访问它指向的对象,或调用任何成员函数(即b-&gt;print())。Base *b = new Base()Derived *d = new Derived() 解决了这个问题,因为他们动态创建对象,并初始化指针,以便指向这些对象。

标签: c++ new-operator virtual-functions


【解决方案1】:

为什么我必须用 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 中只有指针,但您从不创建对象。您的指针不指向对象,它们是未初始化的。取消引用这些指针会调用未定义的行为。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        你正在使用指针,所以它们需要指向一些东西。

        您基本上是在说:“嘿,这个 b 变量指向 Base 对象”,但您从未创建基础对象(使用 new),因此它指向随机内存,并在您尝试将该内存视为Base 对象。

        【讨论】:

          猜你喜欢
          • 2011-08-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-04
          相关资源
          最近更新 更多