[C++] mutable的使用

发布时间:2024年01月23日

文章目录

mutable

  • 当你定义一个类,并且在将类的实例当作参数传递过程中,需要用const Class* cls_ptr方式传递时,会存在一种情况,就是虽然cls_ptr为const,但是你还需要调用该类的方法,修改类中一些属性,来满足自己的需求;这个时候就需要将一些需要修改不受类的const修饰词影响的属性定义为mutable属性。
class Context {
 void set_stream(Stream stream) { stream_ = stream; }
 // 当Context的实例被const修饰时,只能调用`void Function const{}`的方法。否则会报错误。
 const Stream& stream() const { return stream_; }

 mutable Stream stream_;
}

源码参考:https://github.com/google/mediapipe/blob/3e9f86e580ad89519d8e7a228d247ca330d71409/mediapipe/framework/formats/tensor.h#L391

struct MtlResources;
class Tensor {
  class View {
   public:
    // Non-copyable.
    View(const View&) = delete;
    View& operator=(const View&) = delete;

   protected:
    explicit View(std::unique_ptr<absl::MutexLock>&& lock)
        : lock_(std::move(lock)) {}
    std::unique_ptr<absl::MutexLock> lock_;
  };

 public:
  // No resources are allocated here.
  enum class ElementType {
    kNone,
    kFloat16,
    kFloat32,
    kUInt8,
    kInt8,
    kInt32,
    kChar,
    kBool
  };
  struct Shape {
    Shape() = default;
    Shape(std::initializer_list<int> dimensions) : dims(dimensions) {}
    Shape(const std::vector<int>& dimensions) : dims(dimensions) {}
    Shape(std::initializer_list<int> dimensions, bool is_dynamic)
        : dims(dimensions), is_dynamic(is_dynamic) {}
    Shape(const std::vector<int>& dimensions, bool is_dynamic)
        : dims(dimensions), is_dynamic(is_dynamic) {}
    int num_elements() const {
      return std::accumulate(dims.begin(), dims.end(), 1,
                             std::multiplies<int>());
    }
    std::vector<int> dims;
    // The Tensor has dynamic rather than static shape so the TFLite interpreter
    // needs to be reallocated. Only relevant for CPU.
    bool is_dynamic = false;
  };
  // Quantization parameters corresponding to the zero_point and scale value
  // made available by TfLite quantized (uint8/int8) tensors.
  struct QuantizationParameters {
    QuantizationParameters() = default;
    QuantizationParameters(float scale, int zero_point)
        : scale(scale), zero_point(zero_point) {}
    float scale = 1.0f;
    int zero_point = 0;
  };
  ...
  private:
  friend class MtlBufferView;
  void Move(Tensor*);
  void Invalidate();

  ElementType element_type_;
  Shape shape_;
  QuantizationParameters quantization_parameters_;

  // The flags describe the current source of truth resource type.
  enum {
    kValidNone = 0,
    kValidCpu = 1 << 0,
    kValidMetalBuffer = 1 << 1,
    kValidOpenGlBuffer = 1 << 2,
    kValidOpenGlTexture2d = 1 << 3,
    kValidAHardwareBuffer = 1 << 5,
  };
  // A list of resource which are currently allocated and synchronized between
  // each-other: valid_ = kValidCpu | kValidMetalBuffer;
  mutable int valid_ = 0;
  // The mutex is locked by Get*View and is kept by all Views.
  mutable absl::Mutex view_mutex_;

  mutable void* cpu_buffer_ = nullptr;
  void AllocateCpuBuffer() const;
  // Forward declaration of the MtlResources provides compile-time verification
  // of ODR if this header includes any actual code that uses MtlResources.
  mutable std::unique_ptr<MtlResources> mtl_resources_;

#ifdef MEDIAPIPE_TENSOR_USE_AHWB
  mutable std::shared_ptr<HardwareBuffer> ahwb_;
  // Allocates and pools HardwareBuffer instances. Holding the shared_ptr to the
  // pool ensures it outlives the internal ahwb_.
  std::shared_ptr<HardwareBufferPool> hardware_buffer_pool_;
  // Signals when GPU finished writing into SSBO so AHWB can be used then. Or
  // signals when writing into AHWB has been finished so GPU can read from SSBO.
  // Sync and FD are bound together.
  mutable EGLSyncKHR fence_sync_ = EGL_NO_SYNC_KHR;
  // This FD signals when the writing into the SSBO has been finished.
  mutable int ssbo_written_ = -1;
  // An externally set FD that is wrapped with the EGL sync then to synchronize
  // AHWB -> OpenGL SSBO.
  mutable int fence_fd_ = -1;
  // Reading from SSBO has been finished so SSBO can be released.
  mutable GLsync ssbo_read_ = 0;
  // An externally set function that signals when it is safe to release AHWB.
  // If the input parameter is 'true' then wait for the writing to be finished.
  mutable FinishingFunc ahwb_written_;
  mutable std::function<void()> release_callback_;
  bool AllocateAHardwareBuffer(int size_alignment = 0) const;
  void CreateEglSyncAndFd() const;
#endif  // MEDIAPIPE_TENSOR_USE_AHWB
  // Use Ahwb for other views: OpenGL / CPU buffer.
  mutable bool use_ahwb_ = false;
  mutable uint64_t ahwb_tracking_key_ = 0;
  // TODO: Tracks all unique tensors. Can grow to a large number. LRU
  // (Least Recently Used) can be more predicted.
  // The value contains the size alignment parameter.
  static inline absl::flat_hash_map<uint64_t, int> ahwb_usage_track_;
  // Expects the target SSBO to be already bound.
  bool AllocateAhwbMapToSsbo() const;
  bool InsertAhwbToSsboFence() const;
  void MoveAhwbStuff(Tensor* src);
  void ReleaseAhwbStuff();
  void* MapAhwbToCpuRead() const;
  void* MapAhwbToCpuWrite() const;
  void MoveCpuOrSsboToAhwb() const;
  // Set current tracking key, set "use ahwb" if the key is already marked.
  void TrackAhwbUsage(uint64_t key) const;

#if MEDIAPIPE_OPENGL_ES_VERSION >= MEDIAPIPE_OPENGL_ES_30
  mutable std::shared_ptr<mediapipe::GlContext> gl_context_;
  mutable GLuint opengl_texture2d_ = GL_INVALID_INDEX;
  mutable GLuint frame_buffer_ = GL_INVALID_INDEX;
  mutable int texture_width_;
  mutable int texture_height_;
#ifdef __EMSCRIPTEN__
  mutable bool texture_is_half_float_ = false;
#endif  // __EMSCRIPTEN__
  void AllocateOpenGlTexture2d() const;
#if MEDIAPIPE_OPENGL_ES_VERSION >= MEDIAPIPE_OPENGL_ES_31
  mutable GLuint opengl_buffer_ = GL_INVALID_INDEX;
  void AllocateOpenGlBuffer() const;
#endif  // MEDIAPIPE_OPENGL_ES_VERSION >= MEDIAPIPE_OPENGL_ES_31
  bool NeedsHalfFloatRenderTarget() const;
#endif  // MEDIAPIPE_OPENGL_ES_VERSION >= MEDIAPIPE_OPENGL_ES_30
};

其他

上层用非const,底层传递过程中用const修饰的 一个思考就是:在不同调用层级中会使用不同的方法对同样的属性操作,比如在上层,context是非const的,所以可以调用一些set方法,设置一些属性;当传递到下层时,我们希望他们只使用这些设置好的属性,那么我们就将context的实例修饰成const,这样他之能调用这些void Function const{}方法。

  • mutable 的使用思考, 是不是能够管理类,哪些可以被const状态使用,哪些可以被非const使用,这样管理起来可以控制一些类的情况。

Reference

文章来源:https://blog.csdn.net/mingshili/article/details/135765319
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。