2012-08-07 92 views
-2

我正在编写一个简单的着色器管理器,因此我不必一直编写涉及着色器的复制代码,而且遇到了一些问题,这里是函数出现错误:对私有函数中私有静态成员的未定义引用

void ShaderManager::create_program(std::string name) { 
    GLuint vertexshader; 
    GLuint fragmentshader; 

    GLint link_ok = GL_FALSE; 

    if ((vertexshader = create_shader(name + ".v.glsl", GL_VERTEX_SHADER)) == 0) { 
     print_shader_errors(&vertexshader); 
    } 

    if ((fragmentshader = create_shader(name + ".f.glsl", GL_FRAGMENT_SHADER)) == 0) { 
     print_shader_errors(&fragmentshader); 
    } 

    program_values.emplace_back(glCreateProgram()); 
    program_keys.emplace_back(name); 
    glAttachShader(program_values.at(program_values.size()), vertexshader); 
    glAttachShader(program_values.at(program_values.size()), fragmentshader); 
    glLinkProgram(program_values.at(program_values.size())); 

    glGetProgramiv(program_values.at(program_values.size()), GL_LINK_STATUS, &link_ok); 

    if (!link_ok) { 
     std::cout << "The shaders did not link correctly." << "\n"; 
    } 
} 

每一个私有静态成员,我试图访问说同样的事情:

Generator\src\ShaderManager.cpp|33|undefined reference to ShaderManager::program_values' 

我的头文件是这样的:

#ifndef SHADERMANAGER_H 
#define SHADERMANAGER_H 

#include <string> 
#include <vector> 

#include <GL/glew.h> 
#include <GL/glu.h> 
#include <GL/gl.h> 

class ShaderManager { 
    public: 
     ShaderManager(); 
     virtual ~ShaderManager(); 

     static GLuint get_program(std::string shader_name); 
     static int get_index_of_program_key(std::string program_name); 

     static void create_program(std::string name); 
     static bool bind_attribute(std::string shader_name, std::string attribute_name); 
     static bool bind_uniform(std::string shader_name, std::string uniform_name); 

    protected: 
    private: 
     static std::vector<GLuint> program_values; 
     static std::vector<std::string> program_keys; 

     static std::vector<GLuint> attribute_values; 
     static std::vector<std::string> attribute_keys; 

     static std::vector<GLuint> uniform_values; 
     static std::vector<std::string> uniform_keys; 


     static void print_shader_errors(GLuint *shader); 
     static const char* file_read(std::string filename); 
     static GLuint create_shader(std::string filename, GLenum type); 
}; 

#endif // SHADERMANAGER_H 
+0

我试图访问与ShaderManager成员:: program_values.emplace_back() - 也不起作用。 – Darestium 2012-08-07 11:25:39

+1

你是否提供源文件中所有静态成员的定义? – 2012-08-07 11:33:59

+0

重复的http://stackoverflow.com/questions/272900/c-undefined-reference-to-static-class-member – 2012-08-07 11:37:25

回答

3

首先,你accesing program_values.at(program_values.size()),这是访问最后一个元素之后的元素(索引从0开始不是1)和std::vector::at()函数将抛出一个out_of_range异常。 这是访问最后一个元素的正确代码:program_values.at(program_values.size() - 1)或更短program_values.back()

其次,如果你声明的任何静态成员,您需要在一个 CPP文件来定义它,就像这样:

std::vector<GLuint> ShaderManager::program_values; 
std::vector<std::string> ShaderManager::program_keys; 

std::vector<GLuint> ShaderManager::attribute_values; 
std::vector<std::string> ShaderManager::attribute_keys; 

std::vector<GLuint> ShaderManager::uniform_values; 
std::vector<std::string> ShaderManager::uniform_keys; 
+0

“这是缓冲区溢出”它不是缓冲区溢出但超出范围访问,btw在()抛出当你提供错误索引时异常 – 2012-08-07 11:41:42

+0

是的,它会抛出out_of_range异常,它可以通过缓冲区溢出,下溢(意味着缓冲区作为向量元素,而不是分配内存)。 – ErikEsTT 2012-08-07 11:59:43

+0

jeez !!,如果你调用缓冲区溢出/下溢那么为什么没有标准选择out_of_range异常名称是缓冲区溢出/下溢? – 2012-08-07 15:44:22

1

在班级定义中你只有宣称为静态成员program_values。在一些.cpp文件(最好的选择将是所有类的方法定义文件),您需要定义它 - 这样

std::vector<GLuint> ShaderManager::program_values; 

std::vector<GLuint> ShaderManager::program_values(some_constructor_parameters);