Войти
ПрограммированиеФорумОбщее

C++ Как статически проверить что базовый тип - первый? (2 стр)

Страницы: 1 2 3 Следующая »
#15
15:19, 30 июля 2017

gamedeveloper01
> Ты тупой?

> Откуда такие дауны берутся как ты? иди учи C++ понос школьный и не лезь в
> сложные темы.

> Причем тут деструктор тупой даун. Мне нужен указатель для освобождения памяти.
> Читай первый пост тупой баран, я же сказал функция DELETE/FREE, а не
> ДЕСТРУКТОР. Тупая дура. Почуй разницу. Мне нужно по указателю удалить участок
> ПАМЯТИ, ДУРА ТУПАЯ!!!

> А всё из-за чего? да потому что сейчас в микрософтах работают такие же бараны
> как на этом форуме сидят.

> Капец ты упоротый, заметь, я тебя не просил высерать стены бесполезного текста.

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


#16
15:20, 30 июля 2017

Модераторам не пора ли отправить неадекватного ТС в лимб до просветления?

#17
15:25, 30 июля 2017

Kartonagnick
Впечатлён вашей дипломатией!!! :-)) Так красиво мокнуть мордой в дерьмо, браво!!!!

#18
15:35, 30 июля 2017

к слову об Implementation-defined behavior
порядка следования подобъектов базового класса.

любопытное наблюдение.
я вот раньше даже не обращал внимания.

смотрите:

здесь:
http://rextester.com/SMKF44415

+ Показать

адрес наследника совпадает с адресом его первого подобъекта Base1*

а вот здесь:

http://rextester.com/RJJEW38742

+ Показать

адрес наследника совпадает с адресом его второго подобъекта.

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

#19
15:44, 30 июля 2017

Kartonagnick
> эй, скрипач!
> ты...
> горяч...
> как...
> всегда...
> строптив...
Ну вот и доигрался gamedeveloper01 с огнем)

#20
15:52, 30 июля 2017

gamedeveloper01
> Суть в том, что мне нужно вызывать delete для базового указателя, а для этого
> соответственно нужно чтобы указатель был не смещенным, то есть нельзя вызывать
> delete для Base2* указателя (или можно?).
Можно.

#21
15:54, 30 июля 2017

Имхо все методы цепочки классов : папа - дети скомпилированны и лежат по одному адресу(для всей программы), указатели хранят только таблицу указателей на виртуальные методы(которая тоже единственная для каждого уровня класса), которые тоже в единственном экземпляре, созданные при компиляции. Переменные класса выделяются на стэке, или в куче в случае new. Плюс ещё специфичные данные для RTTI, если оно собственно включено. Нету там порядка хранения в зависимости от наследования.
Сразу согласен - куча деталей может отличаться в конкретной реализации компилятора и в зависимости от  организации памяти(ближние/дальние указатели).

#22
16:26, 30 июля 2017

А разве он не должен для приведения указателя от Derived к Base2 использовать dynamic_cast<> вместо сишного/reinterpret_cast<>?

P.S.
А нет, это не reinterpret_cast, как некоторые утверждали. Хотя сишный вид и не проверяет на ту же видимость  предка при конверсии. В Студии.

+ Показать
#23
20:06, 30 июля 2017
#include <iostream>

using namespace std;
template<typename A, typename B> constexpr bool IsFirstBase() { A a; A* aptr = &a;   return (void*)aptr == (B*)aptr; }

#define IS_FIRSTBASE(A,B) IsFirstBase<A,B>()

class B1
{
public:
  constexpr B1() { ; }

private:
  int b{0};
};


class B2
{
public:
  constexpr B2() { ; }

private:
  int b{0};
};

class C: public B1, public B2
{
public:
  constexpr C() { ; }

private:

};

template<bool> void PrintOut() { ; }
template<> void PrintOut<true>() {  std::cout << "true" << std::endl;  }
template<> void PrintOut<false>() { std::cout << "false" << std::endl; }

  
int main() 
{

  PrintOut<IS_FIRSTBASE(C, B1)>();
  PrintOut<IS_FIRSTBASE(C, B2)>();

  //
}
#24
20:56, 30 июля 2017

dave

http://rextester.com/IARM99164

#include <iostream>

using namespace std;
template<typename A, typename B> constexpr bool IsFirstBase() { A a; A* aptr = &a;   return (void*)aptr == (B*)aptr; }

#define IS_FIRSTBASE(A,B) IsFirstBase<A,B>()

class B1
{
public:
  constexpr B1() { ; }

private:
  int b{0};
};


class B2
{
public:
  constexpr B2() { ; }

private:
  int b{0};
};

class C: public B1, public B2
{
public:
  constexpr C() { ; }

private:

};

template<bool> void PrintOut() { ; }
template<> void PrintOut<true>() {  std::cout << "true" << std::endl;  }
template<> void PrintOut<false>() { std::cout << "false" << std::endl; }


enum { value1 = IS_FIRSTBASE(C, B1) };  // <--- ok

enum { value2 = IsFirstBase<C, B2>() }; // <--- error: 
// in constexpr expansion of ‘IsFirstBase<C, B2>()’
// ‘((& a) != 0u)’ is not a constant expression
  
int main() 
{
    PrintOut<IS_FIRSTBASE(C, B1)>();
    PrintOut<IS_FIRSTBASE(C, B2)>();
}

#25
21:07, 30 июля 2017

Kartonagnick

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

#26
23:29, 30 июля 2017

Для вычисления смещений необязательно создавать экземпляры класса.

  C* cptr = (C*)0xff;
  B2* b2ptr = (B2*)cptr;
  B1* b1ptr = (B1*)cptr;

  std::cout << "Offset: " << b2ptr - (void*)cptr << std::endl;
  std::cout << "Offset: " << b1ptr - (void*)cptr << std::endl;
Но в constexpr такая фишка не пройдет. Там нельзя инициировать указатель от integer.
По правилам ц++.
#27
23:54, 30 июля 2017

dave
> Там нельзя инициировать указатель от integer.
а от nullptr?

#28
23:57, 30 июля 2017

cNoNim

От нуля можно, nullptr наверное тоже.
Но смысла нет, так как в этом случае все кастинги дают ноль.

#29
13:53, 11 авг. 2017

gamedeveloper01
> если у Base2 есть virtual destructor, то в функцию delete(void* ptr) попадает
> именно начальный указатель? а не Base2*?
Ответ да. Даже мой собственный тест это показал из ранних постов, просто я неверно прочитал результат, из-за того, что порядок наследования автоматически поменялся, то есть он реально не определён. Но такого ни в одном учебнике и ни в одном ресурсе вы не найдёте, это откровение было написано мной в вышеуказанной фразе. Даже с учетом того что я знаю C++ уже 10 лет. В учебниках написано только про деструкторы и каждый идиот только про это и пишет, а про указатель и про overloaded delete нигде и никто вам не расскажет, радуйтесь. Хотя тут 99% даже не знает что delete можно перегружать и для чего это вообще надо, да я и сам только сейчас с этим столкнулся.

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.