C ++派生类调用基类方法给出了分段错误

时间:2016-08-27 22:50:49

标签: c++

假设我有一个基类和类似于以下的派生类:

#include "Sprite.h"
class Base{
  private:
    int X; //location
    Sprite* sprite;
  public:
    Base(Sprite* sprite){
        sprite = new Sprite(some parameter);
   }
    int getLocation(){
           return X;
    }
    int getWidth(){
         return sprite->getWidth();
    }
}


 class Derived : public Base{
    private:
      Sprite* sprite;  // here I have to redefine it in constructor
    public:
      Derived(Sprite* sprite);  // it's different that base constructor
 { sprite = new Sprite(some parameter);
   sprite->setPriperty(some parameter);
}
 }

当我从其他地方调用Derived :: getLocation()时,没有错误。但是当我调用Derived :: getWidth()时,它给了我分段错误。我必须从基类复制相同的代码(即将getWidth的代码复制到派生类中)以避免错误。我也尝试使用“使用Base :: getWidth;”,但仍然给了我分段错误。似乎如果基类方法包含指针t

2 个答案:

答案 0 :(得分:0)

您可能忘记在构造函数中设置sprite成员变量。执行以下操作:Base(Sprite * s): sprite(s) {}Base(Sprite * s) { this->sprite = s; }

Derived(Sprite* sprite)构造函数应该将sprite传递给父构造函数,如下所示:Derived(Sprite* sprite): Base(sprite) {};

请注意,Base构造函数必须Sprite*的{​​{1}}构造函数传递有效Derived才能处理实例getLocation()

答案 1 :(得分:0)

首先,什么是分段错误?这与Java中的NullPointerException或C#中的NullReferenceException类似。当您尝试访问未分配的内存时会发生这种情况。

为什么会这样?你忘了为sprite指针分配内存,所以它指向一些未经精确处理的内存块。您应该使用new运算符在构造函数中初始化它,如下所示:

Base::Base(Sprite* sprite) {
    this->sprite = new Sprite(sprite);
}

如果您喜欢危险地生活,您还可以执行以下操作:

Base::Base(Sprite* sprite) {
    this->sprite = sprite;
}

但它不安全,因为精灵可以在堆栈上分配,所以这样的代码可能会破坏你的程序造成不明确的行为:

Base * getBase() {
    Sprite sprite;
    //some code operating on sprite
    return new Base(&sprite);
}

这很危险,因为在退出getBase函数后,内存中不再有sprite

<强>更新

所以基本上我从你的评论中得出的结论是你没有调用Base类的正确构造函数。您的Derived构造函数应如下所示:

Derived(Sprite* sprite): Base(sprite) {
   ...
}

如果不这样做,则不要为基类设置sprite的值。您派生类的sprite字段只会隐藏sprite类的Base字段。就像:

int i = 0;
void fun() {
    int i = 20;
}

在示例中,全局i没有改变,因为它被遮蔽了。

您的代码在复制getWidth()类中的Derived方法后仍然有效,因为它正在访问sprite类的Derived字段。要清楚 - 不重写方法getWidth()正在访问sprite类的Base字段,当您覆盖它时,它会访问Derived类的字段。