簡體   English   中英

vector :: emplace_back用於具有私有構造函數的對象

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

我希望我的Timer對象只能通過Timer :: create()創建。 為此,我將構造函數設為私有。 但是,我得到一個編譯器錯誤,說“Timer :: Timer(unsigned int)'是私有的”在new_allocator.h的上下文中。 我怎么解決這個問題?

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;

您可能應該實現自己的分配器,這將是計時器的朋友:

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);
}

最簡單的解決方案是從std::allocator<Timer>重新實現重新rebind以重新綁定到自身,因此vector無法將分配器重新綁定回std::allocator並實現自己的construct來實際創建Timer

您可以使用友元轉移語義來避免必須具有專門的vector分配器。 這有點像依賴注入友誼。 這真的很簡單。 你創建了一個空類,讓自己成為你班級的朋友。 但默認構造函數是私有的,因此只有您的類可以創建它的實例。 但是這個類仍然是可復制的,所以它可以傳遞給任何人。

您的Timer構造函數將是公共的,但它需要其中一個對象作為參數。 因此,只有您的類或它所調用的函數才能直接創建這些對象(復制/移動仍然有效)。

以下是您在代碼中執行此操作的方法( 實例 ):

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