为什么这个函数变量只有在静态时才有效?

Why this function variable only works if it's static?

我正在尝试将一堆声音放在 std::vector 中,因为它非常方便。

我正在使用一个名为 laser 的辅助变量,将声音加载到其中,如果一切正常,则将 push_back 加载到向量中。 当我尝试播放任何声音时,什么也没有发生,甚至连错误消息都没有,如果出现任何问题,应该打印出来。

出于好奇,我制作了 laser staticvoilá,它完美地工作(或者看起来如此)。

我想知道为什么。

头文件:

// audio_system.h
#ifndef KUGE_HEADERS_AUDIO_SYSTEM_H_
#define KUGE_HEADERS_AUDIO_SYSTEM_H_

#include "event.h"
#include "system.h"
#include "../sdl2_wrappers/sdl2_wrappers.h"
#include "../include/resources_path.h"
#include <vector>

namespace kuge {

class AudioSystem : virtual public System {
 public:
  AudioSystem(EventBus& bus): System(bus) {}
  void handleEvent(const Event& event);
  static bool loadResources();

 private:
  static void generateRandomSequence();
  
  static std::vector<ktp::SDL2_Sound> lasers_;
};

} // end namespace kuge

#endif // KUGE_HEADERS_AUDIO_SYSTEM_H_

cpp 文件:

#include "event_bus.h"
#include "audio_system.h"

std::vector<ktp::SDL2_Sound> kuge::AudioSystem::lasers_{};

void kuge::AudioSystem::generateRandomSequence() {}

void kuge::AudioSystem::handleEvent(const Event& event) {
  switch (event.getType()) {
    case EventTypes::LaserFired:
      if (lasers_[0].play() == -1) {
        ktp::logSDLError("laser_.play");
      }
      break;
    
    default:
      break;
  }
}

bool kuge::AudioSystem::loadResources() {
  static ktp::SDL2_Sound laser{};            // here! If I don't make this static, nothing happens
  if (!laser.loadSound(ktp::getResourcesPath() + "sounds/laser2.wav")) {
    return false;
  } else {
    lasers_.push_back(laser);
  }
  ktp::logMessage("AudioSystem: resources loaded.");
  return true;
}

好的,所以根据评论的建议,我进行了以下更改以使 ktp::SDL2_Sound class 遵循 0 的规则,现在无需设置 laser 变量为 static。这解决了问题,但是 我仍然不确定为什么 static

class SDL2_Sound {
 public:
  //~SDL2_Sound() { free(); }       // now I don't need any destructor
  
  bool loadSound(const std::string& path);
  int play(int loops = 0);

 private:
  void free();
  // Mix_Chunk* sound_ = nullptr;   // old raw pointer
  std::shared_ptr<Mix_Chunk> sound_{};
};


/* void ktp::SDL2_Sound::free() {   
  if (sound_ != nullptr) {
    Mix_FreeChunk(sound_);
    sound_ = nullptr;
  }
} */

bool ktp::SDL2_Sound::loadSound(const std::string& path) {
  //free();
  sound_.reset(Mix_LoadWAV(path.c_str()), &Mix_FreeChunk);
  //sound_ = Mix_LoadWAV(path.c_str());
  if (sound_ == nullptr) {
    ktp::logSDLError("Mix_LoadWAV", path);
    return false;
  }
  return true;
}