powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как спрятать кастинг под капот
25 сообщений из 86, страница 2 из 4
Как спрятать кастинг под капот
    #38076213
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychLumix я хочу чтобы строчка b() = new A; помещала адрес этого объекта в указатель globalStore
сейчас с этой задачей справляется строчка b() = (B*) new A;нет, не справляется. в этой строчке - ошибка, и она со всей серьёзностью проявит себя как только класс B начнёт содержать поля, которых нет в родителе. С большой долей вероятности ошибка будет проявляться в самых неожиданных частях программы, казалось бы, никак не связанных с написанным здесь кодом



Можете сформулировать конкретную модель угрозы, если я утверждаю, что в этом случае b() будет 100% использоваться только по А фейсу?? то есть только в условиях типа

Код: plaintext
1.
2.
3.
void usage(A* p);
b() = new A;
usage(b());



вот такое 100% исключено

Код: plaintext
1.
2.
3.
void usage(B* p);
b() = new A;
usage(b());




egorych Всем, всем, всем:
надеюсь вы понимаете, что своими советами вы рождаете чудовище? Он ведь библиотечный код пишет, кому-то ведь достанется _это_

Я наоборот о людях забочусь!! чтобы им было комфортнее работать...
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38076265
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixМожете сформулировать конкретную модель угрозы, если я утверждаю, что в этом случае b() будет 100% использоваться только по А фейсу??
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
#include <iostream>
#include <string.h>
struct A 
{
   virtual ~A() {}  // так и быть, напишу, хотя не хотел, потому что здесь была ещё одна мина зарыта
   virtual void print() { std::cout << "I'm class A" << std::endl; }
};

class B : public A
{
   char *_name;
public:
   B() : _name( new char[ 12 ] ) { strcpy( _name, "I'm class B" ); }
   virtual ~B() { delete[] _name; }

  virtual void print() { std::cout << _name << std::endl; }
};

например

LumixЯ наоборот о людях забочусь!! чтобы им было комфортнее работать...бессонные ночи в отладке чужого кода, на мой взгляд, не то, что можно было назвать комфортом в работе.
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38076301
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixя утверждаю, что в этом случае b() будет 100% использоваться только по А фейсу??задлянафига тогда и globalStore, и b() возвращают B*??? вырази свою мысль прямо и точно:
Код: plaintext
1.
2.
A* globalStore = 0;
A* b()  { return globalStore = globalStore ? globalStore : new B; }

всё, все проблемы решены, клиенты твоей библиотеки не сидят ночами в поисках причин падения безобидного кода, всем бабушкам выплатили пенсию, а ты сидишь счастливый на пляже в обнимку с красивой девушкой и попиваешь молочный коктейль через трубочку. ))
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38076383
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychнапример

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

Код: plaintext
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.
#include <iostream>
#include <string.h>
using namespace std;
struct A 
{
   virtual ~A() {}  // так и быть, напишу, хотя не хотел, потому что здесь была ещё одна мина зарыта
   virtual void print() { std::cout << "I'm class A" << std::endl; }
};

class B : public A
{
   char *_name;
public:
   B() : _name( new char[ 12 ] ) { strcpy( _name, "I'm class B" ); }
   virtual ~B() { delete[] _name; }

  virtual void print() { std::cout << _name << std::endl; }
};

B* globalStore = 0;
B*& b() { return globalStore = globalStore ? globalStore : new B; }

int main()
{
    b() = (B*) new A; // как этот кастинг спрятать в класс
    b()->print(); // пишет A
    b() = new B;
    b()->print(); // пишет B
    b() = (B*) new A;
    b()->print(); // пишет A
    return 0;
}



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

что-то я не припомню, чтобы кому-то приходилось заниматься отладкой кода, который я сдал в боевое использование...наоборот всем нравится, что благодаря моим решениям можно забыть про всякие штуки дрюки с плюсами и сосредоточится на самой программе
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38076389
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл в примере: если первой строчкой вставить b()->print(); то пишет В то есть тоже все круто работает
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38076395
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychзадлянафига тогда и globalStore, и b() возвращают B*??? вырази свою мысль прямо и точно:
Код: plaintext
1.
2.
A* globalStore = 0;
A* b()  { return globalStore = globalStore ? globalStore : new B; }



потому что №1

Код: plaintext
1.
2.
3.
4.
void usage(A* a);
init() { usage(b()); }
event1() { b() = new A; }
event2() { b() = new B; } 



потому что №2

Код: plaintext
1.
b() = getA(); // из сторонней либы которую мы не контроллируем
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38076825
Mozok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixвот такое 100% исключено

Код: plaintext
1.
2.
3.
void usage(B* p);
b() = new A;
usage(b());



Скажите, пожалуйста, каким образом вы гарантируете выполнение этого требования?
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38076847
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MozokСкажите, пожалуйста, каким образом вы гарантируете выполнение этого требования?
Ну как же - строгая гарантия методом "на все воля божия" :)
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38076893
Lumixреинтерпрет-кастом
Код: plaintext
1.
2.
std::shared_ptr<A> globalStore((B*)NULL);
std::shared_ptr<A>& a() { return globalStore = globalStore ? globalStore : std::shared_ptr<A>(new A); }



кстати, а зачем тут ссылка?? ведь вроде shared для того и придумали, чтобы их можно было кидать через копии на границах между функциями... вроде ссылка нужна если бы вы построили решение на обычных умных указателях...
Смотрите в этом случае:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
std::shared_ptr<A> globalStore((B*)NULL);
std::shared_ptr<A>& a() { return globalStore = globalStore ? globalStore : std::shared_ptr<A>(new A); }
void func() {
    // вот это
    a() = std::shared_ptr<A>(new B);

   // идентично этому
   {
        if(!globalStore) globalStore = std::shared_ptr<A>(new A);
        std::shared_ptr<A> &temp = globalStore;
        temp = std::shared_ptr<A>(new B);
   }

   // или этому
   {
        if(!globalStore) globalStore = std::shared_ptr<A>(new A);
        globalStore = std::shared_ptr<A>(new B);
   }
}





А в этом случае, без &:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
std::shared_ptr<A> globalStore((B*)NULL);
std::shared_ptr<A>& a() { return globalStore = globalStore ? globalStore : std::shared_ptr<A>(new A); }
void func() {
    // вот это
    a() = std::shared_ptr<A>(new B);

   // идентично этому
   {
        if(!globalStore) globalStore = std::shared_ptr<A>(new A);
        std::shared_ptr<A> temp = globalStore;
        temp = std::shared_ptr<A>(new B);
   } // и тут же потеряли temp с его new B
}




Позапускайте этот код с & и без:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
#include <iostream>
#include <memory>
using namespace std;

class A { public: int i; A() { i = 0; } };
class B : public A { public: B() { i = 1; } };

std::shared_ptr<A> globalStore((B*)NULL);
std::shared_ptr<A>& a() { return globalStore = globalStore ? globalStore : std::shared_ptr<A>(new A); }

int main()
{
    a() = std::shared_ptr<A>(new B); // как этот кастинг спрятать в класс

    cout << globalStore->i;
    return 0;
} 
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38076895
Поправка :)

А в этом случае, без &:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
std::shared_ptr<A> globalStore((B*)NULL);
std::shared_ptr<A> a() { return globalStore = globalStore ? globalStore : std::shared_ptr<A>(new A); }
void func() {
    // вот это
    a() = std::shared_ptr<A>(new B);

   // идентично этому
   {
        if(!globalStore) globalStore = std::shared_ptr<A>(new A);
        std::shared_ptr<A> temp = globalStore;
        temp = std::shared_ptr<A>(new B);
   } // и тут же потеряли temp с его new B
}
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38076896
egorych Всем, всем, всем:
надеюсь вы понимаете, что своими советами вы рождаете чудовище? Он ведь библиотечный код пишет, кому-то ведь достанется _это_
А как название этой библиотеки?
Врага нужно знать в лицо! :)
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38077288
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
реинтерпрет-кастомПозапускайте этот код с & и без:
[/src]

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

но в примере вы каким-то образом изменили условия задачи и движетесь в каком-то своем направлении, а именно: у вас shared_ptr<A>, а в задаче надо shared_ptr<B>

вот полностью рабочий пример

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
#include <iostream>
#include <boost/shared_ptr.hpp>
using namespace std;
using namespace boost;

class A { public: int i; A() { i = 0; } };
class B : public A { public: B() { i = 1; } };

shared_ptr<B> globalStore((B*)NULL);
shared_ptr<B>& b() { return globalStore = globalStore ? globalStore : shared_ptr<B>(new B); }

int main()
{
    b().reset((B*) new A); // как это же самое записать b() = new A;

    cout << b()->i << " " << globalStore->i;
    return 0;
}
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38078023
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока решение с оператором равно не найдено, запасным вариантом является вот это решение
но в нем динамик кастинг не работает

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
#include <boost/shared_ptr.hpp>
using namespace boost;

class A {};
class B : public A {}; 

shared_ptr<B> globalStore((B*)0);
shared_ptr<B>& b() { return globalStore = globalStore ? globalStore : shared_ptr<B>(new B); }
shared_ptr<B> b(A* p) {  return dynamic_cast<shared_ptr<B> >(shared_ptr<A>(p)); }
shared_ptr<B> b(B* p) {  return shared_ptr<B>(p); }

int main()
{
    b() = b(new A);
    return 0;
}
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38078038
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixegorychзадлянафига тогда и globalStore, и b() возвращают B*??? вырази свою мысль прямо и точно:
Код: plaintext
1.
2.
A* globalStore = 0;
A* b()  { return globalStore = globalStore ? globalStore : new B; }



потому что №1

Код: plaintext
1.
2.
3.
4.
void usage(A* a);
init() { usage(b()); }
event1() { b() = new A; }
event2() { b() = new B; } 



потому что №2

Код: plaintext
1.
b() = getA(); // из сторонней либы которую мы не контроллируем

а во, нашлось ))) не вижу, чем "потому что №1" и "потому что №2" мешает сделать globalStorage указателем на A.
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38078127
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychLumixпропущено...


потому что №1

Код: plaintext
1.
2.
3.
4.
void usage(A* a);
init() { usage(b()); }
event1() { b() = new A; }
event2() { b() = new B; } 



потому что №2

Код: plaintext
1.
b() = getA(); // из сторонней либы которую мы не контроллируем

а во, нашлось ))) не вижу, чем "потому что №1" и "потому что №2" мешает сделать globalStorage указателем на A.


в event2() могут быть обращения c b() как с B
разумеется внутри usage() гарантируется, что B будет использоваться только как А

но принимая во внимание пример, который вы привели тут 13626522 я понимаю, что b() = new A невозможно осуществить в принципе по причинам изложенным в моем выводе вот тут 13627171

пока что я в печали, но потом когда я приободрюсь и полученная инфа уложится в голове, возможно, я пойду по пути что-то типа:

Код: plaintext
1.
2.
3.
usage(a(1))
event1() { a(1) = a(2); }
event2() { a(1) = b(); }
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38078133
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixПока решение с оператором равно не найдено, запасным вариантом является вот это решение
но в нем динамик кастинг не работает

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
#include <boost/shared_ptr.hpp>
using namespace boost;

class A {};
class B : public A {}; 

shared_ptr<B> globalStore((B*)0);
shared_ptr<B>& b() { return globalStore = globalStore ? globalStore : shared_ptr<B>(new B); }
shared_ptr<B> b(A* p) {  return dynamic_cast<shared_ptr<B> >(shared_ptr<A>(p)); }
shared_ptr<B> b(B* p) {  return shared_ptr<B>(p); }

int main()
{
    b() = b(new A);
    return 0;
}



так чисто для истории, если кому-то эта тема в поиск попадется:
с динамик кастингом получился облом
детали смотрите тут 13627171
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38078302
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixв event2() могут быть обращения c b() как с Bа вот тут как раз тебе поможет dynamic_cast:
Код: plaintext
1.
2.
3.
4.
void event2()
{ 
   if( dynamic_cast< B* >( b() ) ) { /* юзаешь его как B */ }
}



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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
// чужой класс
class A
{ 
   public:
     void func1();
     void func2();
};

// чужой getA
A *getA();

class Base
{
   A *_a;
public:
   Base( A a ) : _a( a ) {}
   virtual ~Base() {}

public:
   void func1() { _a->func1(); }
   void func2() { _a->func2(); }
};

Base *getBase() { return Base( getA() ); }

что-то вроде этого, на правах сырой идеи, а не конечной реализации, потому что работать надо через смарт-указатели, и т.д., и т.п.
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38078332
Фотография kosh the best
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix, я искренне надеюсь, что ты еще студент, а не работаешь и твой код не идет в продакшон!
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38078341
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychLumixв event2() могут быть обращения c b() как с Bа вот тут как раз тебе поможет dynamic_cast:
Код: plaintext
1.
2.
3.
4.
void event2()
{ 
   if( dynamic_cast< B* >( b() ) ) { /* юзаешь его как B */ }
}




а зачем, если у нас b() это 100% гарантия, что там B, ведь кастинг A => B оказался невозможен, причем именно благодаря вашим объяснениям!!

если код требует if( dynamic_cast< B* >( b() ) ) { это значит я плохо справляюсь со своей работой и зря ем свой хлеб)))


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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
// чужой класс
class A
{ 
   public:
     void func1();
     void func2();
};

// чужой getA
A *getA();

class Base
{
   A *_a;
public:
   Base( A a ) : _a( a ) {}
   virtual ~Base() {}

public:
   void func1() { _a->func1(); }
   void func2() { _a->func2(); }
};

Base *getBase() { return Base( getA() ); }

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

я понимаю, что это возможно технически, но никто этого делать не станет
тупо по экономическим и временнЫм причинам
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38078342
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kosh the bestLumix, я искренне надеюсь, что ты еще студент, а не работаешь и твой код не идет в продакшон!

я не стану вас разочаровывать, но правда наверное вам не понравится ))))
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38078591
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychLumixв event2() могут быть обращения c b() как с Bа вот тут как раз тебе поможет dynamic_cast:
Код: plaintext
1.
2.
3.
4.
void event2()
{ 
   if( dynamic_cast< B* >( b() ) ) { /* юзаешь его как B */ }
}



я обдумал эту идею
A* b() это невозможно в принципе с сигнатурной точки зрения, потому что в голове пользователей уже сидит правило, что A* a(); B* b();
но то, что вы предложили это по нашим правилам можно оформить так

Код: plaintext
1.
2.
3.
a() = b(); // апкаст
b(a())->drawB(); // "даункаст"
a()->drawB(); // запрещено правилами
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38078670
Mozok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix
Код: plaintext
1.
2.
#include <boost/shared_ptr.hpp>
shared_ptr<B>& b() { return globalStore = globalStore ? globalStore : shared_ptr<B>(new B); }


Это шутка такая?
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38078689
MozokLumix
Код: plaintext
1.
2.
#include <boost/shared_ptr.hpp>
shared_ptr<B>& b() { return globalStore = globalStore ? globalStore : shared_ptr<B>(new B); }


Это шутка такая?
Это пожалуй лучшая строчка из всего кода автора.
Соптимизируется до:
Код: plaintext
1.
2.
3.
4.
5.
#include <boost/shared_ptr.hpp>
shared_ptr<B>& b() { 
 if (!globalStore) globalStore = shared_ptr<B>(new B);
 return globalStore; 
}
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38079153
Фотография kosh the best
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> я не стану вас разочаровывать, но правда наверное вам не понравится ))))
о боже!
просто напиши все это на си
так будет лучше
...
Рейтинг: 0 / 0
Как спрятать кастинг под капот
    #38079243
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kosh the best,

+1 меня тоже всегда поражали выкрутасы в С++ когда формально задача на уровне
постановки уже давно могла быть решена с использованием банальных процедуральных
каллбеков. И API бы выглядел от этого только чище. И все проблемы С++ по большей
части надуманны теми кто пишет код и сам себе Буратино. Не пишите так и проблем
не будет.
...
Рейтинг: 0 / 0
25 сообщений из 86, страница 2 из 4
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как спрятать кастинг под капот
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]