Интеллектуальные указатели могут выборочно скрыть или перенаправить вызовы функции к объектам, которые они переносят?

Пожалуйста, проверьте это:

import webbrowser
chrome_path = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s'
webbrowser.get(chrome_path).open('http://docs.python.org/')
7
задан sharptooth 5 June 2009 в 08:40
поделиться

4 ответа

Вы не можете этого сделать - после перегрузки оператора -> вы застряли - перегруженный оператор будет вести себя так же, независимо от того, что от него правильнее.

Вы можете объявить методы Add () и Release () закрытыми и сделать интеллектуальный указатель другом класса подсчета ссылок.

4
ответ дан 7 December 2019 в 07:50
поделиться
Оператор

-> должен возвращать указатель или объект, который сам поддерживает оператор -> . Может быть рекурсивным. Вы не можете сделать так, чтобы оператор -> вел себя по-разному в зависимости от того, что отображается в правой части -> .

Я не могу придумать ни одного подход, который не предполагает каким-либо образом реплицировать интерфейсы ваших объектов, на которые указывает ваш объект, или требует, чтобы вы создавали объекты, являющиеся общедоступными, производными от объектов, на которые вы указали, с добавлением и освобождением, скрытыми и сделанными частными в производном классе и с использованием Base * pBase = pDerived; pBase-> Add (); трюк для вызова добавления и освобождения из интеллектуального указателя.

3
ответ дан 7 December 2019 в 07:50
поделиться

Я предлагаю вам использовать что-то вроде следующего кода. То, что вы хотите, невозможно , если только вы не хотите добавить небольшое ограничение: объекты должны быть копируемыми (и вы не против использовать эту возможность). В этом случае наследование - хороший вариант.

#include <iostream>
#include <cassert>

using namespace std;

template <class T>
class MySmartPtrHelper : public T
{

public:

    MySmartPtrHelper(T* _t)
        : m_t(*_t)
    {
        delete _t;
        ((T*) this)->Add();
    }

    ~MySmartPtrHelper()
    {
        ((T*) this)->Release(); 
    }

    void Add()
    {
        cout << "MySmartPtrHelper::Add()" << endl;
        //will yield a compile-time error  
        BOOST_STATIC_ASSERT(false) 
    }

    void Release()
    {
        cout << "MySmartPtrHelper::Release()" << endl;
        //will yield a compile-time error  
        BOOST_STATIC_ASSERT(false) 
    }
};

template <class T>
class MySmartPtr
{
   MySmartPtrHelper<T>* m_helper;
   // Uncomment if you want to use boost to manage memory
   // boost::shared_ptr<MySmartPtrHelper<T> > m_helper;

public:

    MySmartPtr(T* _pT)
        : m_helper(new MySmartPtrHelper<T>(_pT))
    {
    }

    MySmartPtrHelper<T>* operator->()
    {
        return m_helper;
    }
};

int main()
{
    MySmartPtr<A> pA(new A());

    pA->Foo();

    //pA->Release(); // this will correctly assert if uncommented.

    return 0;
}
0
ответ дан 7 December 2019 в 07:50
поделиться

Я заставил его работать, изменив перегруженный оператор в MySmartPtr и добавив перегрузку оператор в MySmartPtrHelper:

#include <iostream>
#include <cassert>

using namespace std;

class A
{
public:
    void Add()
    {
        cout << "A::Add" << endl;
    }

    void Release()
    {
        cout << "A::Release" << endl;
    }

    void Foo()
    {
        cout << "A::Foo" << endl;
    }
};

template <class T>
class MySmartPtrHelper
{
    T* m_t;

public:

    MySmartPtrHelper(T* _t)
        : m_t(_t)
    {
        m_t->Add(); 
    }

    ~MySmartPtrHelper()
    {
        m_t->Release(); 
    }

    operator T&()
    {
        return *m_t;
    }

    T* operator->()
    {
        return m_t;
    }


    void Add()
    {
        cout << "MySmartPtrHelper::Add()" << endl;
        assert(false);
    }

    void Release()
    {
        cout << "MySmartPtrHelper::Release()" << endl;
        assert(false);
    }
};

template <class T>
class MySmartPtr
{
    MySmartPtrHelper<T> m_helper;

public:

    MySmartPtr(T* _pT)
        : m_helper(_pT)
    {
    }

    T* operator->()
    {
        return m_helper.operator->();
    }
};

int main()
{
    A a;

    MySmartPtr<A> pA(&a);

    pA->Foo(); 
    //pA->Release(); // this will correctly assert if uncommented.

    return 0;
}

Вывод:

macbook-2:~ $ ./a.out 
A::Add
A::Foo
A::Release
0
ответ дан 7 December 2019 в 07:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: