我很抱歉这个头衔。我好像有问题。我只是一个初学者,如果之前有人问我很抱歉..我无法在这个问题上找到答案。 (当我搜索类,指针和子项时,我得到关于传递父指针或子指针的结果...我不想传递(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()
错误。
由于
答案 0 :(得分:4)
我猜这是因为你指的是一个临时的:
window = &BasicWindow()
一旦该函数退出,window
指向“垃圾”,就会发生不好的事情。
window = new BasicWindow();
不要忘记清理!
答案 1 :(得分:2)
window
是类App
的未初始化指针。因为,您无法调用init
方法。因此,当调用基类window->create()
时,createWindow()
会导致错误。
修改1 :
就目前而言,每件事情在语法上都是正确的,但不确定你想要实现的目标。不要创建临时/无名对象并分配它们。而是使用new
和window = &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()(更好的是放在构造函数中,这就是它们的用途)。
除此之外,更改基类的受保护成员是完全合法的。