Passing SDL_Event
by Reference (&E
) in SDL2 Event Handling
Why pass the SDL_Event
by reference (&E
) to HandleEvent()
?
When passing arguments to functions in C++, we primarily choose between pass-by-value, pass-by-reference, and pass-by-pointer. In the lesson's HandleEvent
function, we pass the SDL_Event
by reference (&E
).
Pass-by-Value vs. Pass-by-Reference
Pass-by-Value: When you pass an argument by value, the function receives a copy of the original variable. Any modifications made to the parameter inside the function affect only the copy, not the original variable outside the function.
void Function(int valueParam) {
valueParam = 10; // Modifies the copy only
}
int main() {
int original = 5;
Function(original);
// original is still 5 here
return 0;
}
Pass-by-Reference: When you pass an argument by reference (using &
in the function parameter declaration), the function receives a reference (an alias) to the original variable. Modifications made to the parameter inside the function directly affect the original variable.
void Function(int& refParam) {
refParam = 10; // Modifies the original variable
}
int main() {
int original = 5;
Function(original);
// original is now 10 here
return 0;
}
Why Use Reference for SDL_Event
?
The main reason for passing SDL_Event E
by reference (SDL_Event& E
) is efficiency.
The SDL_Event
type is a union
. This means it's designed to hold different kinds of event data (keyboard, mouse, window, joystick, etc.) within the same memory location. Some of these nested event structures can be relatively large.
typedef union SDL_Event {
Uint32 type; // Event type
SDL_WindowEvent window; // Window event data (large)
SDL_KeyboardEvent key; // Keyboard event data (large)
SDL_MouseMotionEvent motion; // Mouse motion data
SDL_MouseButtonEvent button; // Mouse button data
// ... other event types
} SDL_Event;
If we passed SDL_Event
by value, the entire structure (potentially large, depending on the event type currently stored) would be copied every time HandleEvent
is called for every object interested in events. In a loop like while (SDL_PollEvent(&E))
, this copying could happen many times per frame, potentially impacting performance, especially if many objects handle events.
Passing by reference avoids this copy. The HandleEvent
function works directly with the original E
variable fetched by SDL_PollEvent
.
Pass-by-const
Reference
In our specific HandleEvent
example, the function only reads the event data; it doesn't modify the event E
itself. In such cases, it's even better practice to pass by constant reference (const SDL_Event& E
):
// Rectangle.h
class Rectangle {
public:
// ...
// Pass by const reference
void HandleEvent(const SDL_Event& E) {
// Now we can only read from E, not write to it
if (E.type == SDL_MOUSEMOTION) {
// ... okay to read E.motion.x
}
// E.type = SDL_QUIT; // This would cause a compile error
}
// ...
};
Using const&
has two benefits:
- Efficiency: It still avoids the copy, just like
&
. - Safety/Clarity: It clearly signals to anyone reading the code that the function will not modify the passed-in event, and the compiler enforces this promise.
While passing by non-const reference (&
) works and avoids the copy, passing by const&
is often preferred when the function only needs read access to the argument.
Rectangles and SDL_Rect
Learn to create, render, and interact with basic rectangles using the SDL_Rect
and SDL_Color
types.