【问题标题】:How to make static class function return non-const reference如何使静态类函数返回非常量引用
【发布时间】:2015-08-03 16:36:28
【问题描述】:

问题:如何从静态类函数返回非常量引用,为什么下面的代码不这样做?

我正在尝试使用 custom allocator 初始化向量,该向量本身是使​​用对自定义内存管理类的引用进行初始化的。看起来是这样的:

参考自定义内存管理类初始化的自定义 std::vector 分配器

template <class T, std::size_t N, std::size_t MAX_SIZE, int ID>
class short_alloc
{
  arena<N, MAX_SIZE, ID>& a_;    //this is the custom memory  mgmt class
... 
public:
  short_alloc(arena<N, MAX_SIZE, ID>& a) noexcept : a_(a) { 
  std::cout<< "copying from reference" << std::endl;
  }

但是,我希望每个模板类型只有 1 个内存管理器,所以我尝试使用单例的 GetInstance() 方法初始化分配器,以便每个模板类型只创建 1 个内存管理器:

单例类确保每组模板参数只有一个内存管理器

template <typename T>
class Singleton
{
 public:
    static T* m_instance;
    static T& GetInstance(){
    if(!m_instance){
      m_instance = new T();
    }
    return m_instance;  
  };
};

用例:

我使用自定义分配器/内存管理器类实例化向量,如下所示:

template <class T, std::size_t N, std::size_t MAX_SIZE, int ID>
class SmallVector {
   public:
      std::vector<T, short_alloc<T, N, MAX_SIZE, 1>> vec;
      SmallVector() : vec(Singleton<arena<N, MAX_SIZE, ID>>::GetInstance()){ 
      std::cout << "running constructor" << std::endl;
      }
   ...
  }

并像这样在int main() 中调用:

SmallVector<int, MAX_BLOCK, MAX_INDIV, 1> s;

但是,这会产生编译器错误:

error: invalid initialization of non-const reference of type 'arena<3200ul, 400ul, 1>& from an rvalue of type 'arena<3200ul, 400ul, 1>*' return &m_instance;

所以看起来我的 Singleton 类正在返回一个 const 引用/r-type 引用。我怎样才能返回一个 l 类型的引用?

【问题讨论】:

  • 指针不是引用。试试return *m_instance;
  • 您的单例已损坏(不是线程安全的,内存泄漏)并且过于复杂(因此会出现这些问题)。最好有一个函数模板返回对本地 static 实例的引用。
  • @KonradRudolph 我没有发布我的完整代码,因为这与解决这个问题无关(析构函数在这里不相关,对吧?)。还有为什么单线程代码会自动出错?
  • 你应该发布一个最小的测试用例,这不是一个。对于基本的“没有返回正确类型的值”错误,这里的代码太多了。
  • 使该代码线程安全的修复不仅使其线程安全,还使其更具可读性。查看当前答案。

标签: c++


【解决方案1】:

返回类型为Singleton&amp;。但是,在 return 语句中,您使用的是

return m_instance;  

应该是这样的

return *m_instance;  

您可以使用以下方法简化您的课程:

template <typename T>
class Singleton
{
 public:
   static T& GetInstance(){

      // By using a static variable, its initialization is 
      // thread-safe, per C++11. That's another reason to
      // prefer this method.
      static T m_instance;

      return m_instance;  
   }
};

【讨论】:

    猜你喜欢
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多