Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.74
Bers
Заблокирован
#1

Не хватает знаний. Не знаю, как на с++ реализовать возможность - C++

15.11.2011, 10:31. Просмотров 2437. Ответов 67
Метки нет (Все метки)

Есть одна вещь, которую у меня сделать никак не получается.

В моей старенькой 2008 студии отсутствуют стандартизированные интеллектуальные указатели.
По этой причине я когда то написал собственные велосипеды для разных типов указателей.

Вот так выглядит прототип метода, который загружает данные в сильнвй указатель (который умеет шариться)


C++
1
2
3
4
void Input(TypeT* &Object); //принять право владения объектом. 
                                //Источник - указатель,
                                // который в конце операции обнулится 
                                //(больше не будет владеть объектом)
Обратите внимание, что на входе ссылка на указатель, а не просто указатель.
Это нужно специально для того, что бы можно было обнулить аргумент.

Вот так выглядит реализация метода:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void_TSharedPointer::Input(TypeT * &pObject)
{
    if(pObject==NULL_PTR) {   Release(); return;  }
 
    //следующее условие не корректно
    //Потому что , ситуация, 
    //когда аргумент указывает туда же,
    //куда и смартпоинтер возникнуть не может
    //Но покамест закроем на это глаза
 
    if(mp_Pointer != pObject)  
    {  
        Release();  
        mp_Pointer = pObject;
        mp_CounterLink=new int(1);
        pObject=NULL_PTR; 
    }
}
Обнуление аргумента гарантирует интеллектуальному указателю, что он действительно будит являться единственным владельцем объекта. И вызывающая сторона не сможет больше никак в обход его ничего сделать с ввереным ему объектом.

Все это здорово, и прекрасно.

Вот так это работает на практике:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
 
    int* ptr= new int;
 
    TSharedPointer<int> test(ptr);
    //теперь значение ptr равно NULL_PTR
    //объект принадлежит сильному указателю
    //а вызывающая сторона 
    //не имеет к нему прямого доступа
 
    EndProgramm();
}

Проблема в том, что я хочу сохранив инвариант сильного указателя, при этом иметь возможность написать вот так:
C++
1
2
3
4
5
6
7
int main()
{
    TSharedPointer<int> test(new int()  );  
    
  
    EndProgramm();
}
Компилятор мне на это пишет:

error C2664: TSharedPointer<TypeT>::TSharedPointer(TypeT *&): невозможно преобразовать параметр 1 из 'int *' в 'int *&'

Вопрос: как сохранить возможность обнуления входящих указателей, но при этом иметь возможность скармливать интеллектуальному указателю оператор new ?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.11.2011, 10:31     Не хватает знаний. Не знаю, как на с++ реализовать возможность
Посмотрите здесь:

Реализовать двусвязный список. В разных узлах одного списка может быть любой объект одного из допустимых типов (своих знаний не хватает) - C++
Вобщем делаю тестовые задания. На одно мне даже ответили, результат отрицательный. Помогите понять если кто поймёт его не так как я или...

Не знаю как реализовать - C++
Итак, пользователь может ввести, а может и ничего не вводить, но програма выводит число через каждые sleep(500) как реализировать...

Возможность доработки ERP системы без соответствующих знаний - C++
Подскажите пожалуйста, заказывал у разработчика ERP систему для себя, но вышло так что человек просто пропал. А сейчас возникла острая...

Не знаю как реализовать.Само задание в изображении. Работа с файлами - C++
Помогите пожалуйста, хотя бы как сделать так, чтобы считались строчки, которые заканчиваются буквой с клавиатуры.

Не знаю как реализовать чтение из файла/запись в файл с особыми условиями - C++
Добрый день! У меня есть файл file.txt с таким содержанием: xxx /x qqq zzz /z aaa ccc /c

Числа считаются равными если они отличаются не более, чем на (10^-12) / c++ / как реализовать эту возможность? - C++
На плоскости заданы три точки А, В и С. Определить, какая из двух последних точек (B или C) расположена ближе к A, и вывести расстояние от...

Взять программу со структурой Person и реализовать возможность использование - C++
помогите с задачей не пойму как делать Взять программу со структурой Person и реализовать возможность использование либо статические...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
15.11.2011, 11:06     Не хватает знаний. Не знаю, как на с++ реализовать возможность #2
Bers, Как вариант просто перегрузить конструктор.
Bers
Заблокирован
15.11.2011, 11:13  [ТС]     Не хватает знаний. Не знаю, как на с++ реализовать возможность #3
Цитата Сообщение от ForEveR Посмотреть сообщение
Bers, Как вариант просто перегрузить конструктор.
Просто перегрузить не получится. Компилятор не сможет разобраться, какой метод вызвать - ссылкой, или без ссылки.
Будит что то вроде:

error C2668: TSharedPointer<TypeT>::Input: неоднозначный вызов перегруженной функции
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
15.11.2011, 11:31     Не хватает знаний. Не знаю, как на с++ реализовать возможность #4
м? не лучший прием.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <stdexcept>
 
template<class T>
class Pointer
{
public:
   Pointer(T*& obj)
   {
      object = obj;
   }
   Pointer(const T* obj)
   {
      object = const_cast<T*>(obj);
   }
   const T& operator *()
   {
      if (object)
      {
         return *object;
      }
      throw std::logic_error("Dereference of null pointer");
   }
private:
   T* object;
};
 
int main()
{
   Pointer<int> p1(new int());
   int* ptr = new int(1);
   Pointer<int> p2(ptr);
   std::cout << *p1 << std::endl;
   std::cout << *p2 << std::endl;
}
Bers
Заблокирован
15.11.2011, 11:40  [ТС]     Не хватает знаний. Не знаю, как на с++ реализовать возможность #5
ForEveR, я думал о таком варианте. Но меня смущает то, что приходится кастовать константность.

Алена в своём блоге пишет:
"Если снимать const с переменной, которая изначально была const, то дальнейшее её использование приведёт к undefined behaviour"(с)

http://alenacpp.blogspot.com/2005/08/c.html

Вот я и подумал.. тут беды никакой не будит? Я с этими константами до сих пор путаюсь
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
15.11.2011, 12:49     Не хватает знаний. Не знаю, как на с++ реализовать возможность #6
Bers, М. В данном случае она константа только как формальный параметр.
Bers
Заблокирован
15.11.2011, 12:57  [ТС]     Не хватает знаний. Не знаю, как на с++ реализовать возможность #7
Цитата Сообщение от ForEveR Посмотреть сообщение
Bers, М. В данном случае она константа только как формальный параметр.
Ну так то да. Номинально же объект не_константный, и номинальный указатель на него тоже не_константный, но почему тогда запускается именно метод с константным аргументом, а не метод с не_константной ссылкой?

Если передавать явный не_константный указатель, то он понимает, что нужно юзать метод с ссылкой, а не с константой.

Но если запихивать new construct(); запускается именно метод с константным указателем.

Как буд то бы оператор new возвращает константный указатель...

Ну и Алена спп тоже панику наводит)

в общем, я так и не совсем уловил принцип работы такого кода
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
15.11.2011, 13:44     Не хватает знаний. Не знаю, как на с++ реализовать возможность #8
Bers, а нужно ли всё это? ИМХО, шаред-птры обычно как раз создают так:
C++
1
shared_ptr< Type > shptr(new Type (...));
Если же программист разрешает ему владеть объектом, которым будет пользоваться также через нативные указатели, то такого программиста надо отшлёпать, и будет ему наука, когда он рантайм еррор получит. Или стояла цель написать именно такой указатель?
Bers
Заблокирован
15.11.2011, 14:04  [ТС]     Не хватает знаний. Не знаю, как на с++ реализовать возможность #9
Цитата Сообщение от silent_1991 Посмотреть сообщение
Если же программист разрешает ему владеть объектом, которым будет пользоваться также через нативные указатели, то такого программиста надо отшлёпать, и будет ему наука, когда он рантайм еррор получит. Или стояла цель написать именно такой указатель?
Задача - получить класс сильного указателя, который обеспечивает безопасность собственной работы.

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

Сильный указатель просто не позволит вызывающей стороне его поломать.
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
15.11.2011, 14:19     Не хватает знаний. Не знаю, как на с++ реализовать возможность #10
Bers, однако сам может поломать вызывающую сторону, да?))
Bers
Заблокирован
15.11.2011, 14:23  [ТС]     Не хватает знаний. Не знаю, как на с++ реализовать возможность #11
Цитата Сообщение от silent_1991 Посмотреть сообщение
Bers, однако сам может поломать вызывающую сторону, да?))
Вариант который предложил ForEveR реально работает. Я никаких проблем не вижу.

Если реально тут нет мины замедленного действия - то это отличный вариант. То, что нужно.

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

Но вдруг там что-то не так. Я даже не до конца понимаю почему если закинуть new , то сработает константный метод.
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
15.11.2011, 14:33     Не хватает знаний. Не знаю, как на с++ реализовать возможность #12
Цитата Сообщение от Bers Посмотреть сообщение
Я никаких проблем не вижу.
Я о том, что на вызывающей стороне указатель становится невалидным. С моей точки зрения, это очень даже нехорошо.

Цитата Сообщение от Bers Посмотреть сообщение
Я даже не до конца понимаю почему если закинуть new , то сработает константный метод.
Потому что отбрасывание константности - первый шаг компилятора при поиске кандидатов перегруженной функции/метода, если полного совпадения не нашлось. Поскольку оно нашлось, этого первого шага не происходит. Если я не ошибаюсь, конечно.

Добавлено через 3 минуты
Нет, похоже, всё-таки ошибаюсь...
Bers
Заблокирован
15.11.2011, 14:35  [ТС]     Не хватает знаний. Не знаю, как на с++ реализовать возможность #13
Цитата Сообщение от silent_1991 Посмотреть сообщение
Я о том, что на вызывающей стороне указатель становится невалидным. С моей точки зрения, это очень даже нехорошо.
Если класс забирает себе право владения объектом, то на вызывающей стороне в принципе не может оставаться валидного указателя.

Иначе какой смысл вообще юзать сильные указатели?

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

Я себе даже представить не могу ситуацию, зачем может понадобится сильный указатель, если при этом нужно что бы оригинал остался валидным.
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
15.11.2011, 15:05     Не хватает знаний. Не знаю, как на с++ реализовать возможность #14
Цитата Сообщение от Bers Посмотреть сообщение
Я себе даже представить не могу ситуацию, зачем может понадобится сильный указатель, если при этом нужно что бы оригинал остался валидным.
Так вот поэтому такие указатели и создают без промежуточных сырых указателей, а выделяя память прямо в аргументе конструктора.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.11.2011, 15:07     Не хватает знаний. Не знаю, как на с++ реализовать возможность
Еще ссылки по теме:

Доработка программы: реализовать возможность работы с шестнадцатеричными числами - C++
здравствуйте! прошу помощи в доработке программы. нужно что бы она могла работать с шестнадцатеричными числами а не только с десятичными...

Подскажите, как лучше всего изучать язык, ежели в академии не дают достаточный объем знаний - C++
хожу на курсы в академию уже 3 месяца, изучаем С++ по либерти, практики нету вообще, просто примеры по книге набираем...в общем туго идет,...

Не знаю как написать - C++
Помогите пожалуйста ! Задание : Дан символьный файл. Получить копию этого файла. совсем не пойму что делать... Есть ли какие либо...

Я не знаю как доработать - C++
Написал код, но очень криво и нифига ничего не работает. Наш препод ничерта не объясняет =( Учу С всего 2 месяца Итак задание:...

Не знаю как выполнить - C++
Помогите пожалуйста с этой задачей: Напишите функцию void compare (char str1, char str2), сравнивающую 2 символьных массива. Функция main...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Bers
Заблокирован
15.11.2011, 15:07  [ТС]     Не хватает знаний. Не знаю, как на с++ реализовать возможность #15
Цитата Сообщение от silent_1991 Посмотреть сообщение
Так вот поэтому такие указатели и создают без промежуточных сырых указателей, а выделяя память прямо в аргументе конструктора.
что произойдёт с бустовским указателем, если я скормлю ему обычный указатель?
Он его не обнулит? То есть бустовский указатель не инвариантен?
Yandex
Объявления
15.11.2011, 15:07     Не хватает знаний. Не знаю, как на с++ реализовать возможность
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru