0

I want to design a base class with private constructor, like this:

#pragma once
#include <bits/stdc++.h>
// base class for singleton
template<typename T>
class Singleton {
 public:
  virtual ~Singleton() {}
  static Singleton& Inst(const T& t) {
    const auto & it = ss_map_.find(t);
    if (it == ss_map_.end()) { printf("Singleton Inst Failed\n"); exit(1); }
    else return *(it->second);
  }

  static void Malloc(const std::vector<T>& v) { 
    for (const auto & i : v) ss_map_[i] = new Singleton(i);
  }     

  static void Release() { 
    for (auto & [_, s] : ss_map_) delete s;
  }     

  static void Release(const T& t) { 
    const auto & it = ss_map_.find(t);
    if (it == ss_map_.end()) { printf("Singleton Release Failed\n"); exit(1); } 
    delete it->second;
    ss_map_.erase(it);
  }     

 protected:
  inline static std::unordered_map<const T, Singleton*> ss_map_;
 private:
  Singleton(const T&) {}
  Singleton& operator =(const Singleton&)=delete;
  Singleton(const Singleton&) = delete;
  Singleton(const Singleton&&) = delete;
};

I make it as a template class, which can let derived class construct with any type.

The derived class looks like this:

class A : public Singleton<int> {
 friend class Singleton;
 private:
  A(int a) : Singleton<int>(a) {}  // PROBLEM HERE, the complier failed to complie.
}

Please see the notes in the code: the constructor of class A fails with the complier error:

base class 'Singleton' has private constructor

How can I make class A work?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
nick
  • 832
  • 3
  • 12

1 Answers1

1

You have defined your friend relationship the wrong way round. The base class needs to declare class A a friend in order to provide access to its private constructor:

#include <iostream>
#include <vector>
#include <unordered_map>

template<typename T>
class Singleton {
    friend class A; // Now, "class A" will have access to private members
public:
// ... and so forth ...

Note: See also: Why should I not #include <bits/stdc++.h>?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • thanks Adrian, that works, but seems not perfect, because i want the derived class can be expanded by others(can't decided in base class), Is there any better methods can achieve this? – nick May 21 '22 at 10:27
  • You can't decide "after the event" what the friends of the base class will be. That would defeat the purpose of having private members, in the first place. – Adrian Mole May 21 '22 at 10:32
  • @nick Maybe you just want the c'tor to be `protected`? (Derived classes will have access, then.) – Adrian Mole May 21 '22 at 10:38