簡體   English   中英

朋友班無法訪問私人數據

[英]Friend class not able to access private data

這是我的課堂宣言:

template <class T>
class Sptr {
    template<typename U> friend class Sptr;

    template <typename T1, typename T2>
    friend bool operator==(const Sptr<T1> &a, const Sptr<T2> &b);

    template <typename U>
    friend Sptr<T> static_pointer_cast(const Sptr<U> &sp);

private:

    RC* ref; //reference counter
    T* obj;//pointer to current obj
    std::function<void()> destroyData;

    bool ok_;

public:

    Sptr();
    ~Sptr();

    template <typename U> 
    Sptr(U *);

    Sptr(const Sptr &);

    template <typename U> 
    Sptr(const Sptr<U> &);

    template <typename U> 
    Sptr<T> &operator=(const Sptr<U> &);

    Sptr<T> &operator=(const Sptr<T> &);

    void reset();

    T* operator->() const
    {return obj;};

    T& operator*() const
    {return *obj;};

    T* get() const
    {return obj;};

    explicit operator bool() const {
          return ok_;
    }

};

下面是抱怨訪問問題的代碼

    template <typename T, typename U>
Sptr<T> static_pointer_cast(const Sptr<U> &sp) {
    //do something
    Sptr<U> answer;

    answer.obj = sp.obj;
    answer.ref = sp.ref;
    answer.destroyData = sp.destroyData;
    answer.ok_ = sp.ok_;

    return answer;
}

當我用以下代碼編譯時:

    Sptr<Derived> sp(new Derived);
    Sptr<Base1> sp2(sp);

    // Sptr<Derived> sp3(sp2); // Should give a syntax error.
    Sptr<Derived> sp3(static_pointer_cast<Derived>(sp2));
    // Sptr<Derived> sp4(dynamic_pointer_cast<Derived>(sp2)); // Should give syntax error about polymorphism.

我已經使其成為一個朋友功能。 為什么無法訪問變量以及如何更正變量?

這有點棘手。 如果替換,則代碼會編譯

template <typename U>
friend Sptr<T> static_pointer_cast(const Sptr<U> &sp);

template <typename T1, typename T2>
friend Sptr<T1> static_pointer_cast(const Sptr<T2> &sp);

原因如下(我不是100%確定,因此請有人批准/不批准):

當實例化Sptr<T> ,例如T = Derived ,結果類定義( Sptr<Derived> )定義了一個具有以下簽名的好友函數:

template <typename U>
friend Sptr<Derived> static_pointer_cast(const Sptr<U> &sp);

因此,這是一個只有一個模板參數的函數。 但是您定義的函數有兩個模板參數。

您對該模板化函數的調用是一個特殊化,如下所示:

Sptr<Derived> static_pointer_cast(const Sptr<Base1> &sp) {
    //do something
    Sptr<Derived> answer;

    answer.obj = sp.obj;
    answer.ref = sp.ref;
    answer.destroyData = sp.destroyData;
    answer.ok_ = sp.ok_;

    return answer;
}

所以它試圖訪問這兩個 Base1 Derived ,但它僅是一個朋友Derived沒有的, Base1 最后一句話很重要,將其更改為帶有兩個模板參數的朋友函數可以解決此問題。

您說過朋友sptr<t> ,這意味着它只能訪問相同類型的sptrs的私有成員。 由於sp2不是sptr(t是派生的),因此它不是朋友。 嘗試:

template< class u, class v> friend sptr<u> static_pointer_cast(const sptr<v> &sp);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM