Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> взаимодействие обычных указателей и shared 
V
    Опции темы
Alek86
Дата 12.11.2007, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



у меня некоторое время уже пишется немелкая прога
и лишь сравнительно недавно я начал использовать boost::shared_ptr

так вот, поскольку раньше я работал с обычными указателями, то подобные конструкции встречались нередко:

Код

MyClass* pClass = new MyClass;
//...
Func1(pClass);
//...
delete pClass;


а вот теперь, как я понял преимущества shared_ptr, функции типа Func1 стали принимать shared_ptr'ы. И получилась ситуация:
Код

class MyClass {     // какой-то класс
public:
    int pI[100];
};
void Func1(MyClass* pMyClass) {    // старая функция
    // код
}
void Func2(boost::shared_ptr<MyClass> vMyClass) {    // новая функция, с бустом
    // код
}

int main() {
    // допустим, в моем старом коде нужно добавить новую функцию, которая реализована и
    // принимает shared_ptr
    MyClass* pMyClass = new MyClass;
    Func1(pMyClass);        // все в порядке
    Func2(boost::shared_ptr<MyClass>(pMyClass));   // shared_ptr удаляет "не свой" объект
    delete pMyClass;      // взрыв, хотя он тут быть как бы и не должон
    system("pause");
}


как бы это можно провернуть, чтобы работало?

Это сообщение отредактировал(а) Alek86 - 12.11.2007, 19:49


--------------------
user posted image    user posted image
PM MAIL   Вверх
JackYF
Дата 12.11.2007, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Alek86 @  12.11.2007,  19:48 Найти цитируемый пост)
boost::shared_ptr<MyClass>(pMyClass)

Передаёшь локальную переменную, она уничтожается сейчас же, не гуд.

Цитата(Alek86 @  12.11.2007,  19:48 Найти цитируемый пост)
Func2(boost::shared_ptr<MyClass>(pMyClass));

Код


...
boost::shared_ptr<MyClass> ptrMyClass(pMyClass);
Func2(ptr);




Цитата(Alek86 @  12.11.2007,  19:48 Найти цитируемый пост)
void Func2(boost::shared_ptr<MyClass> vMyClass)

возможно, 
Код

void Func2(boost::shared_ptr<MyClass>& vMyClass)



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Fazil6
Дата 12.11.2007, 20:39 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Код

int main() {
     
    // допустим, в моем старом коде нужно добавить новую функцию, которая реализована и
    // принимает shared_ptr
    
    boost::shared_ptr<MyClass> pMyClass(new MyClass());

    Func1(pMyClass.get());        // старая функция
    Func2(pMyClass);                 // новая функция
    
    system("pause");
}

PM MAIL   Вверх
Alek86
Дата 12.11.2007, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



в реале все чуток сложнее
 к примеру, так:
Код


class Class1 {
// ...
    void Func2(boost::shared_ptr<MyClass> vMyClass);
// ...
};
class Class2 {
// ...
    MyClass* m_MyClass;
// ...
    Func1() {
        Class1 vClass1;
        vClass1.Func2(boost::shared_ptr<MyClass>(m_MyClass))
    }
// ...
};


выход вижу в том, чтобы хранить рядом с
Код

MyClass* m_MyClass;

еще и 
Код

boost::shared_ptr<MyClass> m_MyClassSharedPtr // в конструкторе записать туда m_MyClass;


но, имхо, не очень удобно, так как надо следить за m_MyClass, чтобы  переназначать m_MyClassSharedPtr, когда m_MyClass меняется....

Добавлено @ 21:34
Fazil6, так бы я догадался, но дело в том, что код старый и работает - не хочется его весь менять

Добавлено через 3 минуты и 32 секунды
а, да, еще его МНОГО

Добавлено через 14 минут и 57 секунд
Цитата(JackYF @  12.11.2007,  20:32 Найти цитируемый пост)
void Func2(boost::shared_ptr<MyClass>& vMyClass)

зачем указатель передавать по ссылке?

Это сообщение отредактировал(а) Alek86 - 12.11.2007, 21:34


--------------------
user posted image    user posted image
PM MAIL   Вверх
JackYF
Дата 12.11.2007, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Alek86 @  12.11.2007,  21:31 Найти цитируемый пост)
зачем указатель передавать по ссылке?

это так, на пробу. Возможно, и незачем.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Fazil6
Дата 12.11.2007, 23:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата(Alek86 @  12.11.2007,  21:31 Найти цитируемый пост)
выход вижу в том, чтобы хранить рядом с


Цитата(Alek86 @  12.11.2007,  21:31 Найти цитируемый пост)
еще и 

заколебешься пыль глотать потом. 
Это будет несопровождаемо. 
Пользуйся либо одним, либо другим 

Код

MyClass* m_MyClass;


заменить на
Код

typedef boost::shared_ptr<MyClass> MyClass_t;

MyClass_t  m_MyClass(new .... );

дальше компилятор скажет где исправить (выкинуть delete и в аргументах). Использование m_MyClass как указателя никак не изменится с изменением на shared_ptr
Но, если стоит выбор между альтернативами, нужно остановиться на чем-то одном. На 2-х стульях тяжело усидеть.
PM MAIL   Вверх
Alek86
Дата 12.11.2007, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



неужели так мало у кого такие проблемы возникали, что при проектировании shared_ptr не учли возможность такой поддержки старого кода? :(


--------------------
user posted image    user posted image
PM MAIL   Вверх
JackYF
Дата 13.11.2007, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Alek86 @  12.11.2007,  23:54 Найти цитируемый пост)
не учли возможность такой поддержки старого кода? :( 

старый код надо заменять, а не поддерживать. Будет у тебя такой бааальшой патч к проекту, состоящий из кучи вот таких вот маленьких замен.

Цитата(Fazil6 @  12.11.2007,  23:44 Найти цитируемый пост)
заколебешься пыль глотать потом. 
Это будет несопровождаемо. 
Пользуйся либо одним, либо другим 

ППКС.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Alek86
Дата 13.11.2007, 00:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(JackYF @  13.11.2007,  00:14 Найти цитируемый пост)
ППКС.

?


Цитата(JackYF @  13.11.2007,  00:14 Найти цитируемый пост)
старый код надо заменять, а не поддерживать.

 smile 
это скажи Страуструпу smile
вообще весь С++ на том и держится, что старый код менять сильно не нужно


--------------------
user posted image    user posted image
PM MAIL   Вверх
Fazil6
Дата 13.11.2007, 00:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата(Alek86 @  13.11.2007,  00:27 Найти цитируемый пост)
вообще весь С++ на том и держится, что старый код менять сильно не нужно

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

Цитата(Alek86 @  12.11.2007,  23:54 Найти цитируемый пост)
неужели так мало у кого такие проблемы возникали, что при проектировании shared_ptr не учли возможность такой поддержки старого кода? :(

какой такой? Чтобы деструктор shared_ptr не вызывал delete ? Нахрен он тогда нужен?
Все, что надо там учли.
PM MAIL   Вверх
Lazin
Дата 13.11.2007, 08:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Если старая функция не сохраняет указатель на объект и не пытается его удалить, то можно ее оставить до поры до времени. Но если старая ф-я гденибудь сохранит указатель на объект, то возможна ситуация когда этот указатель проживет дольше чем все shared_ptr-ы на тот-же объект и если программа попробует к нему обратица, то будет AV (aka segfault). Так-что как уже здесь не раз сказали проще исправить все функции.
До использования shared_ptr я использовал свой велосипед, базовый класс поддерживал подсчет ссылок, а его  деструктор был защищенным. Благодаря этому нельзя было создать такой объект в стеке. Класс указателя который работал с моим указателем был объявлен другом, короче в результате работать с такими объектами возможно только через мою версию смарт-поинтера, и это спасало от многих ошибок
PM MAIL Skype GTalk   Вверх
archimed7592
Дата 14.11.2007, 02:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Извините, если прерву ваш спор ни о чём, но изначальная проблема решается элементарно - достаточно взглянуть на описание класса shared_ptr(можно даже не читать - просто взглянуть).

Код


struct dummy_deleter
{
    void operator()(void *)
    { }
};

int main() {
    // допустим, в моем старом коде нужно добавить новую функцию, которая реализована и
    // принимает shared_ptr
    MyClass* pMyClass = new MyClass;
    Func1(pMyClass);        // все в порядке
    Func2(boost::shared_ptr<MyClass>(pMyClass, dummy_deleter()));   // shared_ptr удаляет "не свой" объект
    delete pMyClass;      // взрыв, хотя он тут быть как бы и не должон
    system("pause");
}



--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Alek86
Дата 14.11.2007, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(archimed7592 @  14.11.2007,  02:07 Найти цитируемый пост)
Извините, если прерву ваш спор ни о чём, но изначальная проблема решается элементарно - достаточно взглянуть на описание класса shared_ptr(можно даже не читать - просто взглянуть).


гы, пепец я внимательный smile
спасибо


--------------------
user posted image    user posted image
PM MAIL   Вверх
archimed7592
Дата 14.11.2007, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Кстати, если уж часто этим пользоваться, то я бы сделал так:
Код

template< class T >
boost::shared_ptr< T > wrap_dumb_ptr(T *ptr)
{
    struct dummy_deleter
    {
        void operator()(T *)
        { }
    };
    return boost::shared_ptr< T >(ptr, dummy_deleter());
}



--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Alek86
Дата 14.11.2007, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



тогда вопрос вдогонку
такой, что, типа, лень самому искать, так что не матюкайтьесь, плиз smile

есть стандартный функтор, что ничего не делает?

Добавлено через 1 минуту и 39 секунд
ЗЫ. скорее всего нету, но "а вдруг?"


--------------------
user posted image    user posted image
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0629 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.