c ++在子类中设置指针变量,并在父类中使用它

时间:2011-02-24 09:27:48

标签: c++ class inheritance variables pointers

我很抱歉这个头衔。我好像有问题。我只是一个初学者,如果之前有人问我很抱歉..我无法在这个问题上找到答案。 (当我搜索类,指针和子项时,我得到关于传递父指针或子指针的结果...我不想传递(this)子指针或父指针,我只想传递一个在子类上初始化的指针。到父母)。我在这里尝试做的更好地通过代码来解释:

class App
{
public:
    virtual void init(void)         { window = &BasicWindow(); }
    virtual void createWindow(void) { window->create(); }

protected:
    Window *window;
};  

class Game : public App
{
public:
    virtual void init(void)         { window = &OpenGLWindow(); }
};

int main ()
{
    App *game = &Game();
    game->init();
    game->createWindow();
    return 0;
}

这合法吗? 我有一个抽象的Window类,BasicWindow和OpenGLWindow从中派生。 但是,当我创建窗口时,我在Access violation reading location函数内的window->create()处出现App::createWindow()错误。

由于

4 个答案:

答案 0 :(得分:4)

我猜这是因为你指的是一个临时的:

window = &BasicWindow()

一旦该函数退出,window指向“垃圾”,就会发生不好的事情。

据推测,你想要做的是创建一个新的窗口实例 - 即

window = new BasicWindow();

不要忘记清理!

答案 1 :(得分:2)

window是类App的未初始化指针。因为,您无法调用init方法。因此,当调用基类window->create()时,createWindow()会导致错误。

修改1

就目前而言,每件事情在语法上都是正确的,但不确定你想要实现的目标。不要创建临时/无名对象并分配它们。而是使用newwindow = &BasicWindow();中的运算符window = &OpenGLWindow();构建它们。由于课程管理资源,因此您应遵循Rule of Three原则。也知道在声明 -

App *game = new Game();

静态类型的操作数( App * )与动态类型(游戏* )不同。在这种情况下,静态类型充当基类,它的析构函数必须是虚拟的,否则行为是未定义的。因此, App类析构函数必须是虚拟的

答案 2 :(得分:2)

我要打算你来自Objective-C吗? ;)

我认为你的问题都源于不了解如何创建C ++对象。

首先:window = &BasicWindow();不是你应该如何创建一个新对象。你需要使用window = new BasicWindow;这会导致在内存中分配BasicWindow的空间,并且将调用BasicWindow的默认构造函数。

你的main()方法有一个类似的错误,但是在这种情况下你不需要使用new来分配它,你可以只声明一个实例,它将在堆栈上创建。

您的主要方法如下:

int main ()
{
    Game game;
    game.createWindow();
    return 0;
}

剩下的问题是你的init方法没有被调用。在C ++中,构造函数被自动调用,并且被命名为与类相同的名称。游戏类的示例默认构造函数是:

Game()  { window = new OpenGLWindow(); }

您需要知道的另一件事是,与目标C不同,在创建对象时会自动调用构造函数的整个层次结构。也就是说,当你创建一个Game实例时,会调用它的构造函数,以及每个基类的构造函数。实际上,基类构造函数称为FIRST。因此,在您的情况下,如果您只是将init方法更改为构造函数,您将分配两个窗口(每种类型之一)并泄漏BasicWindow。哪个不酷。

您应该将它们命名为init,并确保在创建后立即调用它。

总之,试试这个:

class App
{
public:
    virtual void init(void)         { window = new BasicWindow; }
    virtual void createWindow(void) { window->create(); }
protected:
    Window *window;
};

class Game : public App
{
public:
    virtual void init(void)         { window = new OpenGLWindow; }
};

int main ()
{
    Game game;
    game.init();
    game.createWindow();
    return 0;
}

(不要忘记清理新对象!)

编辑(添加示例完成清理):

class App
{
public:
    App() : window( NULL )      {}
    virtual ~App()              { delete window; }
    virtual void init()         { window = new BasicWindow; }
    virtual void createWindow() { window->create(); }
protected:
    Window *window;
};

class Game : public App
{
public:
    virtual void init()         { window = new OpenGLWindow; }
};

int main ()
{
    Game game;
    game.init();
    game.createWindow();
    return 0;
}

答案 3 :(得分:1)

错误可能与您使用临时指针的事实有关。

virtual void init(void)         { window = &BasicWindow(); }

“;”后该指针无效。使用“new”代替“&”。 如果你也想使用窗口指针,你需要调用game-> init()(更好的是放在构造函数中,这就是它们的用途)。

除此之外,更改基类的受保护成员是完全合法的。