简体   繁体   English

vector :: emplace_back用于具有私有构造函数的对象

[英]vector::emplace_back for objects with a private constructor

I want my Timer objects to be created via Timer::create() only. 我希望我的Timer对象只能通过Timer :: create()创建。 For this purpose, I made the constructor private. 为此,我将构造函数设为私有。 However, I get a compiler error saying that "Timer::Timer(unsigned int)' is private" within the context of new_allocator.h. 但是,我得到一个编译器错误,说“Timer :: Timer(unsigned int)'是私有的”在new_allocator.h的上下文中。 How can I solve this problem? 我怎么解决这个问题?

class Timer {
    private:
        int timeLeft;
        Timer(unsigned int ms) : timeLeft(ms) {}

    public:
        static std::vector<Timer> instances;
        static void create(unsigned int ms) {
            instances.emplace_back(ms);
        }
};

std::vector<Timer> Timer::instances;

You probably should implement your own allocator, that will be friend to timer: 您可能应该实现自己的分配器,这将是计时器的朋友:

class Timer {

    struct TimerAllocator: std::allocator<Timer>
    {
        template< class U, class... Args >
        void construct( U* p, Args&&... args )
        {
            ::new((void *)p) U(std::forward<Args>(args)...);
        }

        template< class U > struct rebind { typedef TimerAllocator other; };

    };
    friend class TimerAllocator;

    private:
        int timeLeft;

    Timer(unsigned int ms) : timeLeft(ms) 
    {}

    public:
        static std::vector<Timer, TimerAllocator> instances;
        static void create(unsigned int ms) {
            instances.emplace_back(ms);
        }
};

std::vector<Timer, Timer::TimerAllocator> Timer::instances;

int main()

{
    Timer::create(100);
}

The simplest solution would be derive from std::allocator<Timer> reimplementing rebind to rebind to itself, so vector couldn't rebind allocator back to std::allocator and implement own construct to actually create Timer s. 最简单的解决方案是从std::allocator<Timer>重新实现重新rebind以重新绑定到自身,因此vector无法将分配器重新绑定回std::allocator并实现自己的construct来实际创建Timer

You can use transfer-of-friendship semantics to avoid having to have a specialized vector allocator. 您可以使用友元转移语义来避免必须具有专门的vector分配器。 It's a bit like dependency injection of friendship. 这有点像依赖注入友谊。 This is really quite simple. 这真的很简单。 You create an empty class who's makes itself a friend of your class. 你创建了一个空类,让自己成为你班级的朋友。 But the default constructor is private, so only your class can create instances of it. 但默认构造函数是私有的,因此只有您的类可以创建它的实例。 But the class is still copyable, so it can be passed to anybody. 但是这个类仍然是可复制的,所以它可以传递给任何人。

Your Timer constructor will be public, but it requires one of these objects as an argument. 您的Timer构造函数将是公共的,但它需要其中一个对象作为参数。 Therefore, only your class, or a function called by it, can create these objects directly (copies/moves will still work). 因此,只有您的类或它所调用的函数才能直接创建这些对象(复制/移动仍然有效)。

Here's how you could do that in your code ( live example ): 以下是您在代码中执行此操作的方法( 实例 ):

class TimerFriend
{
public:
  TimerFriend(const TimerFriend&) = default;
  TimerFriend& operator =(const TimerFriend&) = default;

private:
  TimerFriend() {}

  friend class Timer;
}

class Timer {
    private:
        int timeLeft;

    public:
        Timer(unsigned int ms, const TimerFriend&) : timeLeft(ms) {}

        static std::vector<Timer> instances;
        static void create(unsigned int ms) {
            instances.emplace_back(ms, TimerFriend());
        }
};

std::vector<Timer> Timer::instances;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM