【发布时间】:2015-07-14 18:50:07
【问题描述】:
所以,基本上我正在创建一个包装类来创建一个简单的 OpenGL 应用程序。我的想法是在准备好的时候有这样的东西:
#include "application.h"
#include "myClassDerivedFromApp.h"
int main()
{
myClassDerivedFromApp app(1024, 768, "My App Name", 3.3 /*OpenGL Version*/);
app.start();
return 0;
}
所以,基本上这个类使用 GLFW 封装了一个简单的 OpenGL 窗口。这个想法是,当您想创建一个新应用程序时,您只需从 Application 类(我正在编写)派生您的类。使用这个新类,您只需覆盖虚拟方法(mainLoop、initialize 和回调),您将拥有一个工作应用程序。
这是基类:
#pragma once
// Std library
#include <string>
// OpenGL related
#include <GL\glew.h>
#include <GLFW\glfw3.h>
// lh namespace
#include "camera.h"
#include "window.h"
namespace lh
{
//!
//! Class definition of a generic OpenGL Application. Receives the window size,
//! the Application's name and OpenGL's version used.
//!
class Application
{
public:
Application(int windowWidth, int windowHeight, std::string name, float versionOpenGL);
virtual ~Application();
void start();
protected:
virtual void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mode) = 0;
virtual void mouseCallback(GLFWwindow* window, double xpos, double ypos) = 0;
virtual void scrollCallback(GLFWwindow* window, double xoffset, double yoffset) = 0;
virtual void mainLoop() = 0;
virtual void initialize() = 0;
private:
void execute();
// Callbacks
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mode);
static void MouseCallback(GLFWwindow* window, double xpos, double ypos);
static void ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
// Attributes
GLFWwindow* window_;
int width_;
int height_;
std::string name_;
int versionMajor_;
int versionMinor_;
};
}
所以我所做的是将派生类中需要创建的所有函数(位于protected)中声明为纯虚函数。这是实现:
void lh::Application::start()
{
initialize();
execute();
}
void lh::Application::execute()
{
while (glfwWindowShouldClose(window_)) {
glfwPollEvents();
mainLoop();
glfwSwapBuffers(window_);
}
}
基本上方法start调用虚方法initialize和方法execute,调用方法mainLoop。这样,如果我想创建新的东西,我就不必每次都设置 glfw 和窗口,我只需从这个类派生并实现纯虚拟方法。
想法是这样,但是Visual Studio报错我正在调用一个纯虚函数,这可能意味着我不能做我目前正在做的事情。但我没有看到另一种方法(同时确保 Application 类保持抽象)。
注意
我没有包括所有实现(构造函数和回调),因为我认为它们与当前问题无关(构造函数工作正常)。
编辑
这是我测试这个类的方法:
#pragma once
#include "application.h"
class Teste :
public lh::Application
{
public:
Teste(int width, int height, std::string name, float versionOpenGL);
~Teste();
protected:
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mode);
void mouseCallback(GLFWwindow* window, double xpos, double ypos);
void scrollCallback(GLFWwindow* window, double xoffset, double yoffset);
void mainLoop();
void initialize();
};
以及实现:
#include "teste.h"
#include <iostream>
Teste::Teste(int width, int height, std::string name, float versionOpenGL)
: Application(width, height, name, versionOpenGL)
{
}
Teste::~Teste()
{
}
void Teste::initialize()
{
std::cout << "INTIALIZE" << std::endl;
}
void Teste::mainLoop()
{
std::cout << "AAAAAAAA" << std::endl;
}
void Teste::keyCallback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
}
void Teste::mouseCallback(GLFWwindow* window, double xpos, double ypos)
{
}
void Teste::scrollCallback(GLFWwindow* window, double xoffset, double yoffset)
{
}
编辑:
上面的代码运行良好。问题是在构造函数中我最后调用了start(),它调用了虚拟方法。将其从构造函数中移除并将其传递给 main() 函数使其工作正常。
【问题讨论】:
-
确切的错误信息是什么?
-
R6025 - 纯虚函数调用
-
由于这个类有纯虚函数,你不能直接实例化它。如果你试图为了测试,那可能会导致问题。你的另一个问题是,当你从这个类派生一个类时,
start()将调用execute(),它在基类中是私有的,因此不与子类共享......不确定这是否是有意的。 -
你想要的应该可以工作 (ideone.com/SKkuWf) 我目前能想到的唯一原因是在构造函数或析构函数中调用虚函数
-
为了好玩,给自己写一个简单的基类和子类,在构造函数和析构函数中打印出类的名称,以查看调用的顺序。应该清除您的任何剩余问题。
标签: c++ opengl polymorphism glfw