Russian Qt Forum
Апрель 23, 2024, 13:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 ... 3 4 [5]   Вниз
  Печать  
Автор Тема: Ненулевые указатели  (Прочитано 29179 раз)
Авварон
Джедай : наставник для всех
*******
Online Online

Сообщений: 3258


Просмотр профиля
« Ответ #60 : Декабрь 07, 2019, 21:04 »

О том что ты взял выдуманный из пальца пример и его везде тычешь. Типа вот смотрите всё на ссылках ок. Хорошо, а парентом кто владеет? Мы должны догадаться что где-то есть мапа\вектор которая "овнит" детей и их родителей? Потому что в примере этого нет.
Вот пример ноды дерева понятен и самодостаточен - нода овнит детей. А тут? Привели в пример какой-то синтетический main() который иллюстрирует хрен знает что.
А так я бы посоветовал снизить градус, хуями в интернете я могу долго крыть, но мы же здесь не за этим?
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #61 : Декабрь 07, 2019, 22:05 »

Характеристики варианта "ссылочная семантика" сменились с "простой, понятный и логичный" на "грамотный, надежный, качественный".
Ибо, когда в сигнатуре функции из четырёх комбинаций параметров rvalue vs lvalue правильная только одна,
а три приводят к ошибке, это не очень "понятно" и "логично". А каждый раз писать проверки - то уже и не "просто".
Я вот предпочитаю, чтобы типы были выразительными, чтобы сразу было понятно что туда можно передавать, а что нельзя.
И чтобы проверки были зашиты в типе, а не каждый раз их писать.

ничего никуда не сменялось.
само понятие "ссылочная семантика" коррелирует с понятием "инвариант" примерно как "теплое" с "мягким"

судя по выразительному названию not_null,
это - инструмент, который не допустит нулевых указателей.
а вот был ли объект временным, это уже вне его компетенции.

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

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

и напишешь код, который не допустит rvalue там,
где их быть не должно.

Кстати, как будете проверять виртуальные методы?

не нужно ничего проверять.
на самом деле господин Авварон уже продемонстрировал идею:

Код:
struct base
{
    virtual ~base(){}
    virtual void foo(int&) = 0;
    virtual void foo(int&&) = delete;
};

Если вам лично не нужен unique_ptr, и как следствие not_null<unique_ptr>, это же не значит, что и другим они не нужны.

я не понимаю зачем он нужен другим.

единственное объяснение, которое у меня есть на сегодняшний день:

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

А вы в каком уме были, когда этот пример писали? Зачем добавили операцию взятия адреса временного объекта?

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

и в обоих случаях в качестве защиты выступает здравый смысл.

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

Варианты с указателем и gsl::not_null препятствуют передаче временного объекта в функцию.

в том то и дело что не припятствует.
ты код самого not_null смотрел? там нет защиты от временных объектов.

если ты ещё не понял: тебя защищает не not_null, а компилятор gcc,
попробуй скомпилировать под visual studio, и осознай это.


« Последнее редактирование: Декабрь 07, 2019, 23:24 от _Bers » Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #62 : Декабрь 07, 2019, 22:14 »

О том что ты взял выдуманный из пальца пример и его везде тычешь. Типа вот смотрите всё на ссылках ок.

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

человек захотел пронаблюдать ситуацию,
когда класс должен хранить именно указатель,
что бы иметь возможность связываться с различными объектами.
почему нет?

если тебе что-то не нравится - приведи свой пример.
а я посмотрю, как это у тебя получится.


Хорошо, а парентом кто владеет? Мы должны догадаться что где-то есть мапа\вектор которая "овнит" детей и их родителей? Потому что в примере этого нет.
Вот пример ноды дерева понятен и самодостаточен - нода овнит детей. А тут? Привели в пример какой-то синтетический main() который иллюстрирует хрен знает что.
А так я бы посоветовал снизить градус, хуями в интернете я могу долго крыть, но мы же здесь не за этим?

что за бред ты сейчас несешь?
ты пьяный что ли?

Записан
Авварон
Джедай : наставник для всех
*******
Online Online

Сообщений: 3258


Просмотр профиля
« Ответ #63 : Декабрь 08, 2019, 02:04 »


я не понимаю зачем он нужен другим.

единственное объяснение, которое у меня есть на сегодняшний день:

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

ссылка - это observer_ptr
мембер класса - это аналог unique_ptr
аналога shared_ptr в "мире ссылок" тупо нет.

Ты втираешь какую-то дичь, предлагая заменить unique_ptr на ссылку.
Они вообще решают разные задачи. И кто тут теплое с мягким путает?
« Последнее редактирование: Декабрь 08, 2019, 02:14 от Авварон » Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #64 : Декабрь 08, 2019, 13:01 »

не нужно ничего проверять.
на самом деле господин Авварон уже продемонстрировал идею:
...

Если вы предлагаете на каждый not_null постоянно писать такое:
Код
C++ (Qt)
   virtual void setParents(const parent& mother, const parent& father) noexcept = 0;
   virtual void setParents(const parent& mother, parent&& father) = delete;
   virtual void setParents(parent&& mother, const parent& father) = delete;
   virtual void setParents(parent&& mother, parent&& father)      = delete;
и называете это "просто, понятно и логично", то у меня вопросов больше нет.

Я предпочитаю работать хотя бы с таким вариантом:
Код
C++ (Qt)
   virtual void setParents(gsl::not_null<const parent*> mother,
                           gsl::not_null<const parent*> father) noexcept = 0;

Остальные пусть сами решают, какой вариант им больше нравится. А может и другой какой предложат.
Записан

Пока сам не сделаешь...
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #65 : Декабрь 08, 2019, 14:55 »

ссылка - это observer_ptr
мембер класса - это аналог unique_ptr
аналога shared_ptr в "мире ссылок" тупо нет.

по-моему, ты сам сейчас втираешь какую то дичь

Ты втираешь какую-то дичь, предлагая заменить unique_ptr на ссылку.
Они вообще решают разные задачи. И кто тут теплое с мягким путает?
я никогда не предлагал заменить юник на ссылку.

думаю, вчера ты был пьян.
иначе как ещё объяснить твоё нецензурно-агрессивное поведение,
и тот факт, что ты увидел того, чего нет?

Записан
Авварон
Джедай : наставник для всех
*******
Online Online

Сообщений: 3258


Просмотр профиля
« Ответ #66 : Декабрь 08, 2019, 15:37 »

с тобой всё в порядке?
может устал, отдохнуть надо?

То есть начал ты, а агрессивный я?
Записан
Авварон
Джедай : наставник для всех
*******
Online Online

Сообщений: 3258


Просмотр профиля
« Ответ #67 : Декабрь 08, 2019, 15:38 »


я никогда не предлагал заменить юник на ссылку.

Да, ты просто сказал что он нинужен и начал рассказывать о том как всё прекрасно делается на ссылках
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #68 : Декабрь 08, 2019, 15:40 »

Если вы предлагаете на каждый not_null постоянно писать такое:
Код
C++ (Qt)
   virtual void setParents(const parent& mother, const parent& father) noexcept = 0;
   virtual void setParents(const parent& mother, parent&& father) = delete;
   virtual void setParents(parent&& mother, const parent& father) = delete;
   virtual void setParents(parent&& mother, parent&& father)      = delete;
и называете это "просто, понятно и логично", то у меня вопросов больше нет.

не на каждый not_null
not_null вообще не нужен.

я предлагаю простой и логичный дизайн:
Код:
node.setParents(mother, father);

вместо нелогичного:
Код:
node.setParents(&mother, &father);

где ожидается работа с реальным объектом - должны быть реальные объекты,
а не указатели.

и тогда жизнь станет проще.

если тебе так впадлу написать 3 простых записи,
которые простым и понятным для читателя образом запретят rvalue,

ты можешь:
- задействовать шаблон вида:

Код:
#include <iostream>

struct node
{
    virtual ~node(){}
   
    template<class parent1, class parent2>
    void setParents(parent1&& mother, parent2&& father)
    {
        static_assert(
            !::std::is_rvalue_reference<parent1&&>::value,
            "temporary objects 'mother' prohibited"
        );
        static_assert(
            !::std::is_rvalue_reference<parent2&&>::value,
            "temporary objects 'father' prohibited"
        );
        const auto& m = static_cast<const node&>(mother);
        const auto& f = static_cast<const node&>(father);
        this->setParents(m, f);
    }   
    virtual void setParents(const node& mother, const node& father) = 0;
};

struct label: node
{
    virtual void setParents(const node&, const node&){}
};
 
int main()
{
    label mother;
    label father;
    label child;
    node& example = child;
   
    example.setParents(mother, father);
}

- задействовать концепт вида:

Код:
#include <iostream>

struct node
{
    virtual ~node(){}
   
    template<class parent1, class parent2, dfor_lvalue(parent1), dfor_lvalue(parent2) >
    void setParents(parent1&& mother, parent2&& father)
    {
        const auto& m = static_cast<const node&>(mother);
        const auto& f = static_cast<const node&>(father);
        this->setParents(m, f);
    }   
    virtual void setParents(const node& mother, const node& father) = 0;
};

struct label: node
{
    virtual void setParents(const node&, const node&){}
};
 
int main()
{
    label mother;
    label father;
    label child;
    node& example = child;
   
    example.setParents(mother, father);
}



- задействовать вспомогательный инструмент вида:

Код:
#include <iostream>

struct node
{
    virtual ~node(){}
   
    template<class p1, class p2>
    void setParents(lvalue<p1>& mother, lvalue<p2>& father)
    {
        const auto& m = static_cast<const node&>(mother);
        const auto& f = static_cast<const node&>(father);
        this->setParents(m, f);
    }   
    virtual void setParents(const node& mother, const node& father) = 0;
};

struct label: node
{
    virtual void setParents(const node&, const node&){}
};
 
int main()
{
    label mother;
    label father;
    label child;
    node& example = child;
   
    example.setParents(mother, father);
}

где lvalue<p1> - простенькая обертка над ссылками, которая отрезает rvalue

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

что бы в дальнейшем, разработчик наследников имел дело с простым и лаконичным
Код:
virtual void setParents(const node&, const node&){}

что бы пользователем класса было удобно и безопасно.

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

самое удивительное:
ты так и не понял что ли?
not_null не защитит тебя от ошибок с временными объектами.

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

с таким отношение к разработке можешь сразу написать:

Код:
struct node
{
    virtual ~node(){}
    virtual void setParents(const node& mother, const node& father) = 0;
};

и не заморачиваться.
not_null от временных объектов не защищает.










Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #69 : Декабрь 08, 2019, 15:47 »


я никогда не предлагал заменить юник на ссылку.

Да, ты просто сказал что он нинужен и начал рассказывать о том как всё прекрасно делается на ссылках

ау, человек!
ты в каких то своих фантазиях витаешь.
спускайся на землю.

мои цитаты о его ненужности были применимы по отношению к конкретным ситуациям.
я не утверждал, что not_null не нужен вообще.

и я нигде и никогда не утверждал, что "всё прекрасно делается на ссылках".
вот ты откуда этот бред взял?

и при чем тут юник то?
у тебя с логикой вообще как?





Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #70 : Декабрь 08, 2019, 15:53 »

То есть начал ты, а агрессивный я?

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

ты же ведешь себя как женщина.
или как маленький ребенок.
они такое любят: "он пееееервыыыыый наааачааааал!!!!"

Записан
Авварон
Джедай : наставник для всех
*******
Online Online

Сообщений: 3258


Просмотр профиля
« Ответ #71 : Декабрь 08, 2019, 15:57 »

То есть начал ты, а агрессивный я?

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

ты же ведешь себя как женщина.
или как маленький ребенок.
они такое любят: "он пееееервыыыыый наааачааааал!!!!"



Мне было лень выискивать посты адресованные мне, но на последней странице ты уже всех хуями кроешь, хотя я вроде бы попросил снизить градус. Не хочешь, ну давай продолжать в таком же тоне, хуле нет-то.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #72 : Декабрь 08, 2019, 17:14 »

я не утверждал, что not_null не нужен вообще.

not_null вообще не нужен.

Это всё, что нужно знать о нашем грамотее. Сам не может уследить за своими потоками сознания. Наверняка у медиков есть подходящее название для этого.
Записан

Пока сам не сделаешь...
Авварон
Джедай : наставник для всех
*******
Online Online

Сообщений: 3258


Просмотр профиля
« Ответ #73 : Декабрь 08, 2019, 17:24 »

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

Код:
child getChild()
{
    parent mother("ma");
    parent father("pa");
    return child(mother, father);
}

Как viTech писал страницу-две назад, сигнатуры вида foo(const T&), foo(T), template<typename U> foo(U&&) подразумевают, что объект будет скопирован, а не взят его адрес.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #74 : Декабрь 08, 2019, 17:53 »

Ещё нужно понимать разницу между самим объектом, и ассоциативной связью с ним. И что применение инструмента не по назначению (ссылки в "ссылочной семантике"), ведёт к грамотному коду костылестроению. Но не понять это могут не только лишь все Улыбающийся.
Записан

Пока сам не сделаешь...
Страниц: 1 ... 3 4 [5]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.112 секунд. Запросов: 22.