Window Configuration

Deleting Window Copy Operations

Why do we delete the copy constructor and assignment operator in the Window class? What would happen if we didn't?

Abstract art representing computer programming

When we manage resources like SDL windows, we need to be careful about how our objects are copied. Let's explore why deleting these operations is important:

The Problem

Without deleting the copy operations, the compiler would generate default versions that perform shallow copies. This would lead to multiple Window objects trying to manage the same SDL_Window*:

#include <SDL.h>

class Window {
public:
  Window() {
    SDLWindow = SDL_CreateWindow(
      "My Program",
      100, 200, 600, 300,
      0
    );
  }

  ~Window() {
    SDL_DestroyWindow(SDLWindow);
  }

  // Copy operations NOT deleted 

  SDL_Window* SDLWindow;
};

int main() {
  SDL_Init(SDL_INIT_VIDEO);

  {
    Window WindowA;

    // Creates a shallow copy 
    Window WindowB{WindowA};

    // Both WindowA and WindowB now point to the
    // same SDL_Window. When this scope ends,
    // both destructors will try to destroy
    // the same window!
  }

  SDL_Quit();
  return 0;
}
Runtime Error: Attempted to destroy window that was already destroyed

The Solution

By deleting the copy operations, we prevent these issues:

#include <SDL.h>

class Window {
public:
  Window() {
    SDLWindow = SDL_CreateWindow(
      "My Program",
      100, 200, 600, 300,
      0
    );
  }

  ~Window() {
    SDL_DestroyWindow(SDLWindow);
  }

  // Prevent copying
  Window(const Window&) = delete;
  Window& operator=(const Window&) = delete;

  SDL_Window* SDLWindow;
};

Moving Instead of Copying

If you need to transfer window ownership between objects, you can implement move operations instead:

#include <SDL.h>

class Window {
public:
  Window() {
    SDLWindow = SDL_CreateWindow(
      "My Program",
      100, 200, 600, 300, 0
    );
  }

  ~Window() {
    SDL_DestroyWindow(SDLWindow);
  }

  // Prevent copying
  Window(const Window&) = delete;
  Window& operator=(const Window&) = delete;

  // Allow moving
  Window(Window&& Other) noexcept {
    SDLWindow = Other.SDLWindow;
    Other.SDLWindow = nullptr;
  }

  Window& operator=(Window&& Other) noexcept {
    if (SDLWindow) {
      SDL_DestroyWindow(SDLWindow);
    }
    SDLWindow = Other.SDLWindow;
    Other.SDLWindow = nullptr;
    return *this;
  }

  SDL_Window* SDLWindow;
};

This pattern of deleting copy operations while allowing moves is common when working with unique resources like windows, file handles, and network connections.

This Question is from the Lesson:

Window Configuration

Explore window creation, configuration, and event handling using SDL's windowing system

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

Window Configuration

Explore window creation, configuration, and event handling using SDL's windowing system

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 62 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved