Code Fragment-避免null的保护不一定是保护

本文探讨了在软件开发过程中如何妥善处理空指针异常,分析了常见的错误做法及其潜在风险,并提出了有效的应对策略。

经常遇到这种情况,当遇到一个NullPointException的时候,做一些所谓的保护措施,例如下:

public void playVideo(Video video) {
	player.play(video);
}

发现player为null,所以产生了NullPointException,有些处理如下:

public void playVideo(Video video) {
	if (player != null) {
		player.play(video);
	}
}

或者如下:

public void playVideo(Video video) {
	if (player == null) {
		return;
	}
	player.play(video);
}

上面的例子中,而“保护”以后的代码,没有崩溃,却不能正确的工作。在很多场景中,不执行胜过错误的执行。player不能播放,崩溃了,给了我们一个明确的暗示:这个地方有问题!这是我们需要fix的明确信息,而保护”,让这个错误更隐蔽。


这是极其不好的处理,首先我们需要判断这个object为空是否是一种正常的情景,如果不是,这种“保护”反而会出现严重的非预期结果。

对于object:

  1. 必须不为空:通过主动抛出异常信息,说明更多的信息提示,加强表示这种异常情况,当然还是需要修复它为null的问题。
  2. 不应该为空:首先应该查看它什么导致了它为空,并且fix它。
  3. 可能为空的:我们可以通过类似的上面的判断进行处理,必要的时候打印一下log,或 warnning,或info。
一定要统一shader.h吗,不能单独改这个吗#pragma once #include <glad/glad.h> #include <string> #include <iostream> using namespace std; class Shader { public: unsigned int id; //着色器程序(Program Object)的唯一标识符(OpenGL ID) Shader() { id = 0; } Shader(const char* vs, const char* fs) { unsigned int vertex, fragment; //临时变量,分别存储顶点着色器和片段着色器的 OpenGL 对象 ID // 注释:- vertex: 通过 glCreateShader(GL_VERTEX_SHADER) 创建,- fragment: 通过 glCreateShader(GL_FRAGMENT_SHADER) 创建它们是独立编译的着色器单元,在链接前不会生效 vertex = glCreateShader(GL_VERTEX_SHADER); //创建一个顶点着色器对象,该对象将用于加载、编译顶点着色器源代码 fragment = glCreateShader(GL_FRAGMENT_SHADER); //创建一个片段着色器对象,用于处理像素颜色计算(光栅化后) id = glCreateProgram(); //创建一个着色器程序对象,所有着色器必须附加到此程序才能链接运行链接成功后,可通过 glUseProgram(id) 启用整个管线 glShaderSource(vertex, 1, &vs,nullptr); //将 C++ 字符串 vs(顶点着色器源码)绑定到 vertex 着色器对象 glCompileShader(vertex); //编译顶点着色器,将之前设置的源码编译成 GPU 可执行的形式,若语法错误则编译失败,需调用 checkCompileErrors 检查 checkCompileErrors(vertex, "VERTEX"); //检查顶点着色器是否编译成功如果失败,打印详细的错误日志到控制台 glShaderSource(fragment, 1, &fs, nullptr); //将 fs 字符串作为源码传入片段着色器对象 glCompileShader(fragment); //编译片段着色器 checkCompileErrors(fragment, "FRAGMENT"); //检查片段着色器编译状态 glAttachShader(id, vertex); //将已编译的顶点着色器附加到程序对象 id 上 glAttachShader(id, fragment); //将已编译的片段着色器附加到程序对象 id 上 glLinkProgram(id); //链接着色器程序把所有附加的着色器合并为一个可执行程序检查接口匹配性(如 vs 输出与 fs 输入)、全局符号等成功后方可使用 glDeleteShader(vertex); //链接完成后,删除临时的顶点着色器对象 glDeleteShader(fragment); // 删除临时的片段着色器对象 } void use() { glUseProgram(id); //激活当前着色器程序使 OpenGL 渲染管线使用这个 program 进行绘制后续 draw call 都会使用该着色器逻辑 } private: void checkCompileErrors(GLuint shader, std::string type) //用于检查着色器编译或程序链接是否出错 { GLint success; GLchar infoLog[1024]; if (type != "PROGRAM") { glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(shader, 1024, NULL, infoLog); std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; } } else { glGetProgramiv(shader, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shader, 1024, NULL, infoLog); std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; } } } };
最新发布
10-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值