Получение разных экземпляров для связи

Предположим, у меня есть два экземпляра одного класса. У класса есть указатель на некоторые данные, и я хочу, чтобы экземпляры обменивались указателями как часть алгоритма некоторой частной функции, но без ущерба для данных для всех остальных, предоставляя прямой доступ к ним через общедоступную функцию.

Моей первой идеей было добавить статическую переменную типа bool с именем exchange и два метода: закрытый: void requestExchange() и публичный: Data** response(). requestExchange установит для exchange значение true, после чего сразу же последует функция response() из выбранного экземпляра, которая сделает следующее:

if(exchange==true){
    exchange=false;
    return data;
}
else{return...?!

Это было тогда, когда я понял, что у меня нет возможности смоделировать «NO OP», поскольку данные на самом деле могут быть NULL, поэтому предположительно все идет как ответ. Любые идеи относительно того, что можно сделать?

ОБНОВЛЕНИЕ: я немного подумал об этом, и поскольку комбинация запрос-ответ будет вызываться только в контексте, где в результате будет иметь значение NULL (обмен, безусловно, верен), я полагаю, что могу просто вернуть NULL и смоделировать NO OP Сюда. Постороннему NULL в результате будет бесполезен... Но мне все же интересны предложения. Должен быть более хорошо структурированный способ сделать это.


person Epsilon Vector    schedule 22.04.2009    source источник
comment
опубликуйте больше кода, иллюстрирующего то, о чем вы спрашиваете   -  person    schedule 22.04.2009


Ответы (5)


Объекты одного класса могут напрямую обращаться к закрытым данным друг друга. Вы часто видите это, например, в конструкторах копирования.

person marijne    schedule 22.04.2009

Ваше описание проблемы не очень понятно. Почему вы не можете просто сделать response() приватной функцией?

Идея со статическим членом класса чревата опасностью. Что, если две пары таких экземпляров захотят общаться одновременно? Что, если кто-то установит флаг обмена, а затем умрет до того, как дойдет до вызова response()? Как насчет безопасности потоков?

Что касается возврата NO-OP или индикатора ошибки, вы можете либо использовать исключения (для этого они и нужны, но если ваш проект не использует исключения, то не стоит сразу их вводить), либо пойти по пути boost:: по желанию.

person atzz    schedule 22.04.2009

Возможно, лучше разделить ваши проблемы в отношении возврата данных и их обмена.

class Foo
{
public:
   Bar* data()
   {
      return pData;
   }
private:
   void exchangeData(Foo& Rhs)
   {
      if (this != &Rhs)
      {
         Bar* pTmp = pData;
         pData = Rhs.pData;
         Rhs.pData = pTmp;
      }
   }
   Bar* pData;
}

Надеюсь, это соответствует тому, что вы хотите? Вопрос не очень ясен....

person Snazzer    schedule 22.04.2009
comment
Функция exchangeData() может быть общедоступной. - person TonJ; 22.04.2009
comment
Я считаю, что его главная забота заключается в том, что вы можете осуществлять обмен только в частном контексте. - person Snazzer; 22.04.2009

Я, наверное, пропустил суть вашего вопроса. Почему это не делает то, что вы хотите?

class CMyClass  
{
public:
    void ExchangePointerWith( CMyClass& rhs );

private:
    void* m_MyPtr;
};

и:

void CMyClass::ExchangePointerWith(CMyClass &rhs)
{
    void*   tmp= m_MyPtr;
    m_MyPtr= rhs.m_MyPtr;
    rhs.m_MyPtr= tmp;
}
person TonJ    schedule 22.04.2009

Используйте std::swap() и создайте собственный метод подкачки вашего класса, тогда вы знаете, что он должен быть безопасным для исключений. А swap() — это стандартная маршрутизация, которую следует реализовать большинству классов, чтобы сделать их эффективными для STL.

Помните, что класс автоматически становится другом самого себя. Таким образом, он может получить доступ к закрытым переменным-членам другого экземпляра того же класса. См. (Дружественная область в C++)

#include <algorithm>

class myX
{
    public:
        void swap(myX& rhs) throw()
        {
            std::swap(data,rhs.data);
        }
    private:
        void* data;
 };
person Martin York    schedule 22.04.2009