这不是我被困住的问题,而是我正在寻找一种整洁的方式来编写我的代码.
基本上,我正在编写一个事件驱动的应用程序.用户触发事件,事件被发送到适当的对象,对象处理事件.现在我正在编写偶数处理程序方法,我希望使用switch语句来确定如何处理事件.现在,当我正在研究一般结构时,事件类非常简单:
public class Event {
public static enum Action {
MOVE, FOO, BAR
}
private Action action;
private int duration;
public Event(Action action, int duration) {
this.action = action;
this.duration = duration;
}
public Action getAction() {
return action;
}
public int getDuration() {
return duration;
}
Run Code Online (Sandbox Code Playgroud)
然后,在另一个班级,我会有类似的东西:
public void handleEvent(Event evt) {
switch(Event.getAction()) {
case MOVE: doSomething(); break;
case FOO: doSomething(); break;
case BAR: doSomething(); break;
default: break;
}
}
Run Code Online (Sandbox Code Playgroud)
我会喜欢做的就是这样的事情(尽管我当然会坚持开关语句转换成自己的职能,以避免它变成开关和案例讨厌的毛球):
public void handleEvent(Event evt) { …
Run Code Online (Sandbox Code Playgroud) 好的,简单的模板问题.假设我将模板类定义为:
template<typename T>
class foo {
public:
foo(T const& first, T const& second) : first(first), second(second) {}
template<typename C>
void bar(C& container, T const& baz) {
//...
}
private:
T first;
T second;
}
Run Code Online (Sandbox Code Playgroud)
问题是关于我的bar函数...我需要它能够使用某种标准容器,这就是为什么我包含模板/ typename C部分来定义容器类型.但显然这不是正确的方法,因为我的测试类然后抱怨:
错误:此范围内未声明"bar"
那么我将如何以正确的方式实现我的条形函数呢?也就是说,作为我的模板类的函数,使用任意容器类型...我的模板类的其余部分工作正常(有其他函数不会导致错误),它只是一个有问题的函数.
编辑:好的,所以特定的函数(bar)是eraseInRange函数,它擦除指定范围内的所有元素:
void eraseInRange(C& container, T const& firstElement, T const& secondElement) {...}
Run Code Online (Sandbox Code Playgroud)
它将如何使用的一个例子是:
eraseInRange(v, 7, 19);
Run Code Online (Sandbox Code Playgroud)
其中v是这种情况下的向量.
编辑2:傻我!我本来应该在我班级之外宣布这个功能,而不是在它里面...这是非常令人沮丧的错误.无论如何,感谢大家的帮助,虽然问题有点不同,但信息确实帮助我构建了这个功能,因为在找到原来的问题后,我确实得到了一些其他令人愉快的错误.所以谢谢!
我想要完成的是:在我的场景顶部绘制我的场景的深度图(以便更近的物体更暗,更远的物体更亮)
问题:我似乎不明白如何将正确的纹理坐标从我的顶点着色器传递到我的片段着色器。
所以我创建了我的 FBO,以及深度贴图被绘制到的纹理......不是我完全确定我在做什么,但无论如何,它有效。我测试使用固定功能管道绘制纹理,它看起来就像它应该的(深度图)。
但是试图在我的着色器中使用它是行不通的......
这是我的渲染方法中绑定纹理的部分:
glActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D, depthTextureId);
glUniform1i(depthMapUniform, 7);
glUseProgram(shaderProgram);
look(); //updates my viewing matrix
box.render(); //renders box VBO
Run Code Online (Sandbox Code Playgroud)
所以……我觉得这样对吗?也许?不知道为什么纹理 7,这只是我正在检查的教程中的内容...
这是我的顶点着色器中的重要内容:
out vec4 ShadowCoord;
void main() {
gl_Position = PMatrix * (VMatrix * MMatrix) * gl_Vertex; //projection, view and model matrices
ShadowCoord = gl_MultiTexCoord0; //something I kept seeing in examples, was hoping it would work.
}
Run Code Online (Sandbox Code Playgroud)
Aaand,片段着色器:
in vec4 ShadowCoord;
in vec3 Color; //passed from vertex shader, didn't include the code for it though. Just the vertex …
Run Code Online (Sandbox Code Playgroud) 只是一个简单的问题,如果我有一个模板类:
template <typename T>
class foo {
public:
bool operator!=(foo& other) const {
//...
}
}
Run Code Online (Sandbox Code Playgroud)
然后我继承了所说的课程:
template <typename T>
class bar : public foo<T> {
//...
}
Run Code Online (Sandbox Code Playgroud)
运算符重载是否继承?如果没有,我将如何实现它以便它... ...因为目前在我的测试类中,这会带来一个错误:
for (bar<int> i(baz); i != bar<int>(); i++) {}
Run Code Online (Sandbox Code Playgroud)
++运算符在bar类中实现,因此可以工作,但!=运算符显然不会被继承.错误消息是:
error: no match for 'operator!=' in 'i != bar<int>(0u, 0u)'
note: candidate is: bool foo<T>::operator!=(foo<T>&) const [with T = int]
Run Code Online (Sandbox Code Playgroud)
这几乎总结了我遇到的问题,所以我只是想知道如何继承运算符重载.
关于正确处理析构函数的相对简单的问题......
首先,我有一个类似这样的课程:
class Foo {
public:
ReleaseObjects() {
for (std::map<size_t, Object*>::iterator iter = objects.begin(); iter != objects.end(); iter++) {
delete (*iter).second;
}
objects.clear();
}
private:
std::map<size_t,Object*> objects;
}
Run Code Online (Sandbox Code Playgroud)
因此该函数只删除使用"new"创建的对象.问题是一个Object类:
class Bar : public Object {
public:
Bar() {
baz = new Baz();
}
~Bar() { delete baz; }
private:
Baz* baz;
}
Run Code Online (Sandbox Code Playgroud)
如果我向Foo添加一个类型Baz对象,然后尝试ReleaseObjects(),我会得到一个内存泄漏(valgrind).问题指向baz被泄露,我猜这意味着bar中的析构函数从未被调用过?所以我想知道的是在尝试销毁该对象时如何调用Bar析构函数(我不能改变Bar类,但我可以改变Foo).
编辑:哎呀,抱歉语法错误.无论如何,感谢所有的回复,愚蠢的我忘了在我的Baz课程中实现一个正确的析构函数!哦,Baz实际上是一个模板类,但我认为Baz与我的问题有点无关,而且问题是Bar中的析构函数没有被调用......好吧,我错了,毕竟问题出现在Baz中.但再次感谢,我想我从这里弄清楚了!
我应该实现一个从容器中删除一系列值的函数.所以
eraseRange(v, 1.5, 24);
Run Code Online (Sandbox Code Playgroud)
例如,从容器v中删除大于1.5且小于24的任何值.并且我的函数适用于列表,我在其中使用:
container.erase(remove_if(container.begin(), container.end(), rg));
Run Code Online (Sandbox Code Playgroud)
rg检查它是否在范围内(该部分的实现不是问题,所以我不打算详细说明).
但是,当为向量调用eraseRange并使用类似的方法擦除值时,只有第一个值被擦除.所以,如果我有一个数字从1到10的向量,我打电话给:
eraseRange(v, 3, 7);
Run Code Online (Sandbox Code Playgroud)
只有3个被删除.
现在这通常不会成为问题,我只想使用迭代器来检查值.除了这个特定的练习,明确禁止/ while/do循环...
所以问题似乎是具有随机访问迭代器的容器.而且我不确定如何实施替代方案.救命?
我不知道我在valgrind中的错误报告告诉我的是什么......但这是我的代码中与该问题相关的部分:
template<typename T>
struct CompareEvents {
public:
bool operator()(const T a, const T b) const {
return a.time < b.time ? true : false;
}
};
class EventManager {
public:
void EventManager::SendEvent(int delay, size_t sender, size_t receiver, size_t eventId) {
if (delay > 0) {
eventQueue.insert(Event((GetTime() + delay), sender, receiver, eventId)); //line 55
}
}
private:
std::set<Event, CompareEvents<Event>> eventQueue;
}
Run Code Online (Sandbox Code Playgroud)
事件只是一个简单的结构,它有四个参数(时间,发送者,接收者和ID).
从我的测试类调用SendEvent导致一个可爱的seg错误......看起来像这样(valgrind):
==998== Invalid read of size 8
==998== at 0x40D544: std::_Rb_tree<Event, Event, std::_Identity<Event>, CompareEvents<Event>, std::allocator<Event> >::_M_begin() (stl_tree.h:493)
==998== by …
Run Code Online (Sandbox Code Playgroud) c++ ×5
templates ×2
containers ×1
destructor ×1
enums ×1
erase ×1
glsl ×1
inheritance ×1
java ×1
memory-leaks ×1
nested ×1
opengl ×1
remove-if ×1
set ×1
stl ×1
valgrind ×1