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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Идиома RAII и указатли. Передать указатель в функц, ию. Помогите написать оператор. 
V
    Опции темы
neosapient
Дата 5.11.2013, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Здравствуйте.

Помогите дописать для шаблона оператор, который синтаксически правильно передаст указатель [1] в функцию [10].

Есть указатель на объект. При входе в функцию указатель инициализиоуется оператором new. Затем при выходе, объект удаляется оператором delete.
Проблема в том, что в программе может возникнуть исключение и объект окажется не удаленным. По этому воспользовался идиомой RAII (Получение ресурса есть инициализация) и написал шаблон. 

Шаблон. При инициализации указателя, тот зануляется в конструкторе [2]. Далее указатель может инициализироваться через оператор new [9]: для этого в шабллоне перегружен оператор присваивания [4]. При выходе из зоны видимости объект удаляется и шаблон в своем деструкторе вызвает для указателя оператор delete [3]. 

Код

#pragma once

template <typename Type>
class raii
{
    Type* ptr; // <-[1]
public:
    raii()
        : ptr(NULL) // <-[2]
    { }

    ~raii()
    { 
        if(ptr){ // <-[3]
            delete ptr;
            ptr = NULL;
        }
    }

    raii& operator=(const Type* p)  // <-[4]
    {
        ptr = (Type*)p;
        return (*this);
    }

    Type* operator -> () {
        return (ptr); 
    }
};


Рассмотрим тестовый пример (пока без использования шаблона, т.е. пункт [7] включен, а [8] закомментирован). Объект типа Obj имеет метод для деления div(). Если делить на ноль, то будет выкинуто исключение [5]. Все исключения ловятся в конструкции try catch в функции main(). 
Функция main() вызывает функцню foo(), в которой создается Obj. Далее указатель на Obj передается в функцию boo() [10]. Внутри функции boo() у переданного объкта вызывается метод div(), и передаются параметры 1 и 0 (для 0 вызывается исключение [6]).

Надеюсь, пример доступен для понимания. 

Код

#include "raii.hpp"
#include <iostream>

class Obj{
    double value;
public:
    Obj(double v)
        : value(v)
    { }

    double div(int d)
    {
        if(d==0)
            throw std::exception("exeption!!!"); // <-[5]
        return value/d;
    }

};

void boo(Obj* obj)
{
    std::cout << obj->div(1) << std::endl;
    std::cout << obj->div(0) << std::endl; // <-[6]
}

void foo()
{
    //Obj* obj;   // <-[7]
    raii<Obj> obj;  // <-[8]
    obj = new Obj(42); // <-[9]
    boo(obj); // <-[10]
}

int _tmain(int argc, _TCHAR* argv[])
{
    try{
        foo();
        std::cout << "all good";
        return 0;
    }
    catch(const std::exception& e){
        std::cerr << e.what();
        return -1;
    }
}


Теперь рассмотрим другой пример, с использованием шаблона, т.е. пункт [7] закомментируем, а пункт [8] включим.
При компиляции выдается сообщение об ошибке, ругается на передачу объекта raii вместо указателя [10]
1>c:\users\me\desktop\test_raii\test.cpp(35) : error C2664: 'boo' : cannot convert parameter 1 from 'raii<Type>' to 'Obj *'
1>        with
1>        [
1>            Type=Obj
1>        ]
1>        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called


Помогите дописать для шаблона оператор, который синтаксически правильно передаст указатель [1] в функцию [10].

P.S.
Пример прикреплен к посту

Это сообщение отредактировал(а) neosapient - 5.11.2013, 11:48
PM MAIL   Вверх
bsa
Дата 5.11.2013, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 85
Всего: 196



Добавь operator Type*() { return ptr; }

Но это плохой код. Смотри std::unique_ptr в качестве примера.
PM   Вверх
neosapient
Дата 5.11.2013, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Спасибо!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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