簡體   English   中英

訪問由std :: shared_ptr包裝的類的運算符重載

[英]accessing operator overloading of class which is wrapped by std::shared_ptr

這個想法是,我希望由std::shared_ptr包裝的類仍然可以像不是指針一樣被使用,例如,包裝完類后仍可以使用在類中定義的operator =通過std::shared_ptr

例如

template <class Ty> class shared_ptr_proxy : public std::shared_ptr<Ty> {
public:
    template<class Other> shared_ptr_proxy& operator=(const Other& rhs)
    {
        (*this->get()) = rhs;
        return *this;
    }
    template<class Other> explicit shared_ptr_proxy(Other * ptr) 
        : std::shared_ptr<Ty>(ptr){};
};

// usage :
shared_ptr_proxy<float> obj = shared_ptr_proxy<float>(new float);
obj = 3.14;

它的工作,但有沒有一種方法,我不需要創建shared_ptr_proxy或從std::shared_ptr繼承一個類?

如果我這樣做,是否有需要注意的警告?

這取決於您想要的代理。 完整的代理可能會使它看起來完全像您具有的值,因此您需要提供轉換運算符。

但是,在這種情況下,從shared_ptr繼承可能不是一個好主意,因為您可能正在繼承要依賴隱式轉換的函數。

比較排序項目的方式:

#include <memory>
#include <vector>
#include <algorithm>
#include <iostream>

template <class Ty> class shared_ptr_proxy   {
    std::shared_ptr<Ty> ptr;
public:
    template<class Other> explicit shared_ptr_proxy(Other * p) 
        : ptr(std::shared_ptr<Ty>(p)){};

    template<class Other> shared_ptr_proxy& operator=(const Other& other)
    {
        *ptr = other;
        return *this;
    }

    operator Ty& () { return *ptr; }
    operator const Ty& () const { return *ptr; }
};

int main()
{
    std::vector<shared_ptr_proxy<int> > vec {
        shared_ptr_proxy<int>(new int(10)), 
        shared_ptr_proxy<int>(new int(11)), 
        shared_ptr_proxy<int>(new int(9))
    };
    vec.back() = 8;  //use assignment
    std::sort(vec.begin(), vec.end());  //sort based on integer (not pointer) comparison
    for (unsigned i = 0; i != vec.size(); ++i) {
        std::cout << vec[i] << ' ';  //output stored values
    }
}

#include <memory>
#include <vector>
#include <algorithm>
#include <iostream>

template <class Ty> class shared_ptr_proxy : public std::shared_ptr<Ty>   {
public:
    template<class Other> explicit shared_ptr_proxy(Other * p) 
        : std::shared_ptr<Ty>(p){};

    template<class Other> shared_ptr_proxy& operator=(const Other& other)
    {
        *this->get()= other;
        return *this;
    }

    operator Ty& () { return *this->get(); }
    operator const Ty& () const { return *this->get(); }
};

int main()
{
    std::vector<shared_ptr_proxy<int> > vec {
        shared_ptr_proxy<int>(new int(10)), 
        shared_ptr_proxy<int>(new int(11)), 
        shared_ptr_proxy<int>(new int(9))
    };
    vec.back() = 8;  //the only thing that works
    std::sort(vec.begin(), vec.end());  //sort based on pointer values
    for (unsigned i = 0; i != vec.size(); ++i) {
        std::cout << vec[i] << ' ';  //outputs addresses
    }
}

operator=必須是您正在重載的類的成員。 所以不,您不能真正做到非侵入式。

不,您不能透明地執行此操作,如果可以的話,可能會非常令人困惑。

抱歉,我不認為沒有繼承或沒有自定義包裝程序就無法擺脫shared_ptr ,不能在shared_ptr定義之外重載operator = ,並且由於shared_ptr的性質,在這種情況下不建議繼承。 但是,如果您編寫一個自定義包裝器,則可以使其足夠通用,以使其適用於每種類型。

這僅在C ++ 11中是可能的,即使在那里也很困難。 您需要使用decltypestd::declval來推斷運算符的返回類型,並需要使用rvalue引用和std::forward來完美地轉發參數。 有關示例,請參見此問題及其答案。

如該問題中所述,我實現了一個指針包裝器類: http : //frigocoder.dyndns.org/svn/Frigo/Lang/ref

但是,與您想要的相比有一些區別:

  • operator = (ref&)operator = (ref&&)僅復制指針。 但是,由於這個原因以及代理的復制構造函數,隱式operator = (const T&)了復制構造和指針復制,而不是賦值或獲取地址。 這是我的自覺選擇,如果共享對象,分配會產生問題,並且從堆棧分配的對象獲取指針是不安全的。

  • 由於GCC的未實現功能,采用復合賦值運算符(如operator +=的返回類型不起作用。 這是沒有問題的,因為它們被重新解釋: x += y調用x = (x + y) ,進行復制/移動構造和指針復制。 這也是我的有意識的選擇,以保持共享對象不變。

  • 使用Boehm GC收集的垃圾(而不是參考文獻)進行計數。 這也是我的自覺選擇,引用計數是垃圾收集的非常糟糕的選擇。

解引用共享指針:

std::shared_ptr<float> obj(new float);
*obj = 3.14;

暫無
暫無

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

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