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

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 68, средняя оценка - 4.74
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
#1

[C++] Взятие адреса конструктора. Физическое время существование объекта. - C++

16.02.2012, 15:40. Просмотров 8371. Ответов 69
Метки нет (Все метки)

1. конструктор.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A
{
 
int a;
public:
A():a(555){};
~A(){}
 
};
 
int main()
{
A* pa = &A();//это вызов конструктора - явный. он используется контейнерами stl.
//вывод - конструктор можно вызвать явно и с параметрами и без.
// возвращается некий указатель на начало объекта
};
Вопрос: если объект начинается с конструктора, то полученный нами указатель - будет указывать на конструктор? и только высокоуровневые ограничения не дают нам видеть его среди членов объекта и работать с ней. Если это так, то спутившись на уровень ниже, туда где нет ограничений, по идее получив данный адрес - мы можем сделать call по этому адресу. другое дело какой эффект получится, непонятно.
поэтому обращаюсь к тебе Evg как к очень опытному специалисту знающему "нутро".
вот мы сделали бинарник. в нем программа, в ней создаются объекты классов.
мне сложно судить где буду лежать эти объекты, предположу что в .text
если мое предположение верно, то после отображения в память, можно будет обратится к конструктору зная его адрес, поскольку никакие высокоуровневые вещи не будут мешать.

вопрос 2

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
class A
{
public:
    int a;
A():a(555){};
~A(){}
 
};
 
int main()
{
A* pa = &A();//это временный объект и сразу после создания будет вызван деструктор
 
int mass [1000];
 
for(int i=0;i<1000;i++)//это вызовы для мебели и зачистки останков временных объектов
    mass[i] = i;
 
 
pa->~A(); //не вызывается. объекта нет НО
int z = pa->a; //дело его живет. z ==555
 
 
return 0;
};
каково время жизни поля класса после уничтожения объекта класса?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.02.2012, 15:40     [C++] Взятие адреса конструктора. Физическое время существование объекта.
Посмотрите здесь:

Почему лучше инициализировать объекты класса во время инициализации конструктора? C++
Существование объекта C++
C++ Реализовать динамический массив объектов, учитывая, что параметры для конструктора у каждого объекта разные
ООП в C++: Вызов родительского конструктора с параметром при создании объекта дочернего класса C++
C++ Взятие адреса у константной переменной при объявлении
[Двусвязные списки] Добавление по индексу. Взятие адреса по индексу C++
C++ Взятие адреса в аргументе
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт CАвтор FAQ
17292 / 5540 / 347
Регистрация: 30.03.2009
Сообщений: 15,083
Записей в блоге: 26
16.02.2012, 22:27     [C++] Взятие адреса конструктора. Физическое время существование объекта. #41
Цитата Сообщение от AzaKendler Посмотреть сообщение
а из загруженного файла функциями api все то угодно
Я же говорил, что "средствами языка". Ковыряясь в бинарном файле или используя всякие сторонние средства можно сделать всё, что угодно. Так или иначе вся защищённость Си++ - она только на уровне языка программирования, но не на уровне бинарного кода. Об этом я писал здесь: функции класса раздела private реализуються так же как и раздела public? в смысле виртуальных функций, дружественных функций, и т.д.

Ну и пара ссылок, которые тебе, возможно, пригодятся:
http://www.cyberforum.ru/cpp-beginne...tml#post171823
http://www.cyberforum.ru/cpp-beginne...tml#post171884

Цитата Сообщение от AzaKendler Посмотреть сообщение
и последний вопрос
А вопрос-то где?
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
16.02.2012, 23:25  [ТС]     [C++] Взятие адреса конструктора. Физическое время существование объекта. #42
Цитата Сообщение от Evg Посмотреть сообщение
А вопрос-то где?
его задал Bers. Шутка.
Вопросов более нет. спасибо за подробные объяснения

Добавлено через 44 минуты
Evg, кхм. сори за назойливость. и все таки вопрос вернее пару


1.
Цитата Сообщение от Evg Посмотреть сообщение
Запись "A()" означает создать объект типа A и вызвать для него дефолтный конструктор
что означает создать объект растолкуй. как то увязано с выделением памяти? а если она уже выделена?

например

C++
1
2
3
class A;
char buf[100];
A* pa = new(buf) A;// сконструировать конструктором в уже готовой области
здесь не оно? не чисто конструктор вызовется? Если нет то поясни процесс создания немного плиз.
ValeryS
Модератор
6482 / 4948 / 455
Регистрация: 14.02.2011
Сообщений: 16,389
16.02.2012, 23:49     [C++] Взятие адреса конструктора. Физическое время существование объекта. #43
может вот так понятней будет
C++
1
2
3
4
5
6
7
8
class A
{
int a1;
int a2;
};
.......
A c1;
A c2;
после этого
у тебя в памяти будет два блока по 2 инта
c1 и c2
и один конструктор
сколько объектов не создавай конструктор( а равно и другие методы) будут присутствовать в одном экземпляре в них незаметно передается this

возми IDA
напиши простейшую программу и компильни в трех вариантах
дебиг
релиз с отладочной информацией
релиз без отладочной информации
и дизасемблируй
в третьем варианте даже имен не будет

например в моем примере даже конструктора не будет
выделится память и все
соответственно что искать
если есть виртуальные функции то может быть можно получить указатель на таблицу виртуальных функций(хотя маловероятно) а потом прсканировать память и найти кто считывает этот адрес и записывает в себя, это и есть конструктор ( а так же деструктор), но как это реализовать я не знаю
Evg
Эксперт CАвтор FAQ
17292 / 5540 / 347
Регистрация: 30.03.2009
Сообщений: 15,083
Записей в блоге: 26
16.02.2012, 23:55     [C++] Взятие адреса конструктора. Физическое время существование объекта. #44
Цитата Сообщение от AzaKendler Посмотреть сообщение
что означает создать объект растолкуй
Ты статью читал? Просто мне уже интересно, то читал, но не понял или не читал? Потому как все эти вопросы там описывались

Добавлено через 1 минуту
В посте 32 то же самое расписывал. Ты никак не можешь понять одну простую вещь: правильно поставленный вопрос - это уже половина ответа. А ворох разнообразных ответов говорит о том, что вопрос поставлен невнятно и каждый ответивший понимает его по своему. Я, если честно, не могу понять, что тебе не понятно
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 08:59  [ТС]     [C++] Взятие адреса конструктора. Физическое время существование объекта. #45
конечно читал. попробую сформулировать
Прежде всего хочется указать на одну из самых распространённых ошибок начинающих: они считают, что конструктор выделяет память для объекта (создаёт объект), а деструктор - освобождает память (удаляет объект). Это неверно! Процесс выделения памяти для объекта описан в предыдущей главе. А конструктор только инициализирует объект (т.е. задаёт объекту некоторое начальное значение). Очень важно это понимать.
конструктор - "обычная функция" задача которой инициализировать поля объекта класса не более. все верно?
Итак, вкратце подведём итоги по выделению памяти для объекта и его времени жизни:
Автоматический объект. Время жизни начинается в момент входа в процедуру или лексический блок, в котором объявлен объект и заканчивается при выходе из процедуры или лексического блока.
зашли в лексический блок {} память выделилась верно?



мы имеем

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A;
int main()
{
//зашли в блок - выделилась память под a,pa, buf. что для A() произойдет?
 
A a; -// вызвался конструктор A();
 
A(); // ? какая то временная неименованная переменная при входе в блок была создана для хранения этого?
 
char buf[100];
A* pa = new(buf) A; //вызвался конструктор A();
 
return 0;
}
прокомментируй пожалуйста эти три случая. просто на пальцах. хочу четкого понимания.
Evg
Эксперт CАвтор FAQ
17292 / 5540 / 347
Регистрация: 30.03.2009
Сообщений: 15,083
Записей в блоге: 26
17.02.2012, 09:03     [C++] Взятие адреса конструктора. Физическое время существование объекта. #46
Цитата Сообщение от AzaKendler Посмотреть сообщение
зашли в блок - выделилась память под a,pa, buf. что для A() произойдет?
C++
1
A();
См. пост #32

Цитата Сообщение от AzaKendler Посмотреть сообщение
C++
1
A a; // вызвался конструктор A();
Сделались две вещи: родился объект "a" (т.е. появился участок памяти, в котором живут данные объекта) и вызвался конструктор (который в этот участок памяти записал некоторые значения)

Цитата Сообщение от AzaKendler Посмотреть сообщение
C++
1
A* pa = new(buf) A; вызвался конструктор A();
Память под объект уже выделена до этого момента (в качестве её выступает buff[100]). Здесь только вызовется конструктор, который проинициализирует значениями память, соответствующую буферу, в предположении, что там теперь живёт экземпляр класса A.
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 09:14  [ТС]     [C++] Взятие адреса конструктора. Физическое время существование объекта. #47
Цитата Сообщение от Evg Посмотреть сообщение
Сообщение от AzaKendler
Код C++
1
A a; // вызвался конструктор A();
Сделались две вещи: родился объект "a" (т.е. появился участок памяти, в котором живут данные объекта) и вызвался конструктор (который в этот участок памяти записал некоторые значения)
вот тут вопрос. разве этот участок памяти не появился при входе в лексический блок?

Добавлено через 1 минуту
Цитата Сообщение от AzaKendler Посмотреть сообщение
class A;
int main()
{
//зашли в блок - выделилась память под a,pa, buf.
не здесь память под него была выделена?

Добавлено через 5 минут
Итак, вкратце подведём итоги по выделению памяти для объекта и его времени жизни:
Автоматический объект. Время жизни начинается в момент входа в процедуру или лексический блок, в котором объявлен объект и заканчивается при выходе из процедуры или лексического блока.
пользовательские классы отличаются от встроенных типов?
память под них выделяется не при входе в блок а в месте их объявления?
Evg
Эксперт CАвтор FAQ
17292 / 5540 / 347
Регистрация: 30.03.2009
Сообщений: 15,083
Записей в блоге: 26
17.02.2012, 09:20     [C++] Взятие адреса конструктора. Физическое время существование объекта. #48
Цитата Сообщение от AzaKendler Посмотреть сообщение
разве этот участок памяти не появился при входе в лексический блок?
Технически (физически) участок памяти родился при входе в процедуру. Если говорить ещё честнее, то гораздо раньше, но в особенности реализации стека в операционных системах сейчас лезть не стОит. Ну "участок памяти" и "объект" - это не тождественно равные фичи. Объект логически появился в той точке кода, которая соответствует строке "A a;". "Логически" означает, что только после этой точки компилятор (а точнее, стандарт Си++) тебе гарантирует, что в этом участке памяти будут находиться данные, которые соответствуют твоему объекту. А от момента появления этой памяти и до момента привязки объекта к этой памяти, что находится в этой памяти - никому неизвестно

Добавлено через 1 минуту
Цитата Сообщение от AzaKendler Посмотреть сообщение
не здесь память под него была выделена?
Технически - да. Логически - нет. При условии, что мы работаем на "обычном" процессоре. Возможно, что в природе существуют специализированные процессоры, в которых технически память появляется только в тот момент, который соответствует логическому рождению объекта.

Добавлено через 1 минуту
Цитата Сообщение от AzaKendler Посмотреть сообщение
пользовательские классы отличаются от встроенных типов?
память под них выделяется не при входе в блок а в месте их объявления?
Как уже говорил, технически - при входе в блок, логически - в точке объявления объекта. С такого низкого уровня вопросом пока никто не интересовался. Надо обдумать, как это аккуратно в статью вставить. При этом так, чтобы у людей, которые такими тонкостями не заморачиаются, не возникло лишних недопониманий на ровном месте

Добавлено через 1 минуту
Всё это я уже писал, но не теми словами
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 09:24  [ТС]     [C++] Взятие адреса конструктора. Физическое время существование объекта. #49
Цитата Сообщение от Evg Посмотреть сообщение
"A a;". "Логически" означает, что только после этой точки компилятор (а точнее, стандарт Си++) тебе гарантирует, что в этом участке памяти будут находиться данные, которые соответствуют твоему объекту. А от момента появления этой памяти и до момента привязки объекта к этой памяти, что находится в этой памяти - никому неизвестно
поясни немного процесс логической привязки. получается место под "объект" мы получили давно, когда образ файла закатался в память, последней вызывается точка входа в программу, если я все точно понял из спецификации PE. в нашем случае это main. значит к моменту вызова в мэйн - память "в этом конкретном случае" уже готова для помещения.
что же будет тем самым логическим рождением объекта? вызов констуктора, который и инициализирует тот кусок памяти, который уже был выделен ранее?
C++
1
A a; //что есть логическое появление объекта? вызов конструктора который прокачает участок памяти с данными?
Добавлено через 1 минуту
да, был бы очень признателен. если ты в статье немного осветишь эту тему. наверно это особо никому не интересно, но все таки было бы здорово.
спасибо.
Evg
Эксперт CАвтор FAQ
17292 / 5540 / 347
Регистрация: 30.03.2009
Сообщений: 15,083
Записей в блоге: 26
17.02.2012, 09:35     [C++] Взятие адреса конструктора. Физическое время существование объекта. #50
Цитата Сообщение от AzaKendler Посмотреть сообщение
получается место под "объект" мы получили давно
Нет. Тут речь идёт только об автоматических объектах, а потому в исполняемом файле (в образе программы в памяти) этой памяти нет. Эта память есть ТОЛЬКО во время работы функции

C
1
2
3
4
5
6
7
8
9
int main (void)
{
  int x; // логически объект "x" родился в этой точке
  x = 0; // инициализация (как бы конструктор, но для простоты просто обнуление)
  int y; // логически объект "y" родился в этой точке
  y = 0;
  int z; // логически объект "y" родился в этой точке
  z = 0;
}
реально в процессе исполнения код "на пальцах будет таким"

Код
# Код процедуры main
main:
  выделим место в стеке размером 12 байт (сразу для всех трёх переменных)
  при работе со стеком у нас всегда есть некий указатель текущего окна в стеке
  (FP = frame pointer), через который в функции мы адресуемся ко всем переменным.
  Как правило стек растёт в сторону уменьшения адресов, а потому обращение
  ко всем объектам в стеке идёт с отрицательными смещениями

  # int x;
  # логическое рождение объекта "x". Технически оно не выражается ни в какие
  # машинные операции, т.к. память под все автоматические объекты процедуры
  # мы выделили скопом при входе в процедуру. Однако начиная с этого момента
  # память, зарезервированная под "x", начинает принадлежать только объекту "x",
  # и компилятор больше не имеет права использовать его под свои нужды (ну мало
  # ли там что ему понадобилось)

  # x = 0;
  код, который делает запись нуля по адресу FP - 4

  # int y;
  # тут всё аналогично "x"

  # y = 0;
  код, который делает запись нуля по адресу FP - 8

  # int z;
  # тут всё аналогично "x" и "y"

  # z = 0;
  код, который делает запись нуля по адресу FP - 12
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 09:56  [ТС]     [C++] Взятие адреса конструктора. Физическое время существование объекта. #51
# int x;
# логическое рождение объекта "x". Технически оно не выражается ни в какие
# машинные операции
т.е. это некая конструкция для компиллятора? метка для него. так?
Evg
Эксперт CАвтор FAQ
17292 / 5540 / 347
Регистрация: 30.03.2009
Сообщений: 15,083
Записей в блоге: 26
17.02.2012, 09:58     [C++] Взятие адреса конструктора. Физическое время существование объекта. #52
"Это" - это что?
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 10:00  [ТС]     [C++] Взятие адреса конструктора. Физическое время существование объекта. #53
Цитата Сообщение от AzaKendler Посмотреть сообщение
логическое рождение объекта "x"
ты пишешь что в машинных операциях не выражено.
Evg
Эксперт CАвтор FAQ
17292 / 5540 / 347
Регистрация: 30.03.2009
Сообщений: 15,083
Записей в блоге: 26
17.02.2012, 10:13     [C++] Взятие адреса конструктора. Физическое время существование объекта. #54
"int x;" - это просто объявление объекта. Как реализует это компилятор - это его внутреннее дело. Я говорю тебе в первую очередь так, как оно реализовано на i386 (да и на большинстве современных процессорах). Если компилятор вместо однократного выделения в стеке 12 байт построит 3 раза выделение по 4 байта, то точно так же получится корректный код (возможно, что в каких-то отладочных режимах какой-нибудь компилятор так и поступает). Единственное, что требуется от компилятора - это то, что с момента определения объекта и до момента выхода из блока компилятор обязан обеспечить возможность чтения-записи объекта. Каким способом сделает это компилятор - это уже заботы исключительно компилятора
ValeryS
Модератор
6482 / 4948 / 455
Регистрация: 14.02.2011
Сообщений: 16,389
17.02.2012, 12:30     [C++] Взятие адреса конструктора. Физическое время существование объекта. #55
Цитата Сообщение от Evg Посмотреть сообщение
Если компилятор вместо однократного выделения в стеке 12 байт построит 3 раза выделение по 4 байта, то точно так же получится корректный код
или просто отдаст 3 регистра (будет сие означать выделение памяти)???
вот такое творение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class A
{
public:
int a;
};
int fnc()
{
A d;
A c;
d.a=4;
c.a=5;
return d.a+c.a
}
может превратится вот в такой код
Assembler
1
2
3
4
mov edx,4
mov eax,5
add eax,edx
ret
где здесь конструктор,где выделение памяти (а объекты есть)

или даже в такой
Assembler
1
2
mov eax,9
ret
оптимизатор посчитал лишним заморочку с объектами и выдал просто ответ
а может вообще выбросил функцию оставив значение

ни о каких объектах, конструкторах в бинарном коде говорить не приходится
о чем Evg, пытается донести
Evg
Эксперт CАвтор FAQ
17292 / 5540 / 347
Регистрация: 30.03.2009
Сообщений: 15,083
Записей в блоге: 26
17.02.2012, 12:53     [C++] Взятие адреса конструктора. Физическое время существование объекта. #56
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от AzaKendler Посмотреть сообщение
Evg, ну это понятно. тогда его вызов извне ограничен только в контексте языка с++ и концепции классов я прав?
и теоретически мы можем вызвать конструктор, поскольку он является обычной функцией найдя его адрес в загруженном в память файле. верно?
По поводу того, как читерскими способами (т.е. неязыковыми средствами) вызвать конструктор

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h>
 
class A
{
    int a;
  public:
    A (int);
};
 
void func (void)
{
}
 
A::A (int x) : a(55555555 + x)
{
}
 
long delta = 0;
 
int main (void)
{
  /* Читерская структура, которая соотвествует классу A */
  struct s
  {
    int x;
  };
 
  /* Читерская переменная, которую подсунем в конструктор в качестве
   * экземпляра класса A */
  struct s str;
  str.x = 0;
 
  /* Читерский прототип функции, который соответсвует конструктору A::A(int) */
  typedef void (*fptr_t) (struct s*, int);
 
  /* Адрес подставной функции func */
  long addr = (long) &func;
 
  /* Вычисляем адрес конструктора, предполагая, что компилятор расположит его
  * в памяти сразу после функции func */
  addr += delta;
 
  /* Читерским образом вызываем конструктор */
  ((fptr_t)addr) (&str, 1);
 
  /* для контроля проверим, что читерский объект действительно должным
   * образом проинициализирован */
  printf ("str.x=%d\n", str.x);
 
  return 0;
}
Мы здесь основываемся на том, что через адрес функции func мы сможем вычислить адрес конструктора (т.к. в памяти они будут лежать рядом по статическим адресам). Поскольку средствами языка нельзя взять адрес на конструктор, то мы это можем сделать, анализируя исполняемый файл. Пример я запускал на linux'е (оно покатит и на любом unix'е). Под виндой запускать ровно таким же образом, если кто-то знает, как там смотреть символьную таблицу исполняемого файла

Сначала делаем предварительный запуск с целью выяснения адреса

Код
$ g++ t.cc -fno-exceptions -O2
$ readelf --symbol a.out | grep FUNC
   Num:    Value  Size Type    Bind   Vis      Ndx Name
...
    44: 08048400     5 FUNC    GLOBAL DEFAULT   13 _Z4funcv
    47: 08048430    19 FUNC    GLOBAL DEFAULT   13 _ZN1AC1Ei
...
Метка _Z4funcv соответствует нашей функции func, метка _ZN1AC1Ei соответствует конструктору A::A(int). Во второй колонке написаны адреса этих функций (по научному Value). Вычисляем разницу адресов 0x08048430 - 0x08048400 = 0x30, а затем модифицируем программу, заменив "long delta = 0;" на "long delta = 0x30;". И далее запускаем:

Код
$ g++ t.cc -fno-exceptions -O2
$ ./a.out
str.x=55555556
Следует понимать, что в обоих случаях надо производить запуск компилятора с одними и теми же опциями, чтобы гарантировать одинаковость сгенерированного кода. В моём случае разница адресов получилась 0x30, но на каждой отдельной машине (на которой стоит своя версия компилятора) эта разница будет своя. Здесь я опираюсь на то, что компилятор gcc строит метод функции таким образом, как если бы эта была функция с скрытым первым параметром. Другие компиляторы, к пример, вправе поступать подругому, вправе изменять программные соглашения по передаче параметров в методы класса и т.п. Я здесь всего лишь показал, что технически это возможно, нужно только знать, как это делать

Добавлено через 2 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
или просто отдаст 3 регистра (будет сие означать выделение памяти)???
Будет. Строго говоря, вместо "выделение памяти" правильным будет назвать "выделение аппаратного ресурса", что есть память либо регистр. Но сточки зрения понимания вопроса это непринципиально. Людям удобнее оперировать понятием "память" и не заморачиваться тем, что ещё есть "регситр". В режиме без оптимизаций основная масса компиляторов все переменные складывает в память, и для экспериментов этого вполне достаточно
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 13:28  [ТС]     [C++] Взятие адреса конструктора. Физическое время существование объекта. #57
Evg, про читерский метод мне подумалось что как ни крути а придется собрать бинарный файл и посмотреть таки дамп, чтобы увидеть хоть какое то смещение до конструктора. отличная подсказка с функцией! спасибо. я как раз размышлял с какого бока можно подойти.

выходит мы имеем просто функцию, которая лежит себе в сегменте кода, имеет определенный прототип и ей абсолютно все равно кого
инициализировать лишь бы подходил под прототип. так?
и то это если функция "сложная" и компиллятор не решит обойтись вообще без нее.

Добавлено через 8 минут
инфо
Цитата Сообщение от ValeryS Посмотреть сообщение
Код ASM

mov edx,4
mov eax,5
add eax,edx
ret
Цитата Сообщение от ValeryS Посмотреть сообщение
од C++

class A
{
public:
int a;
};
int fnc()
{
A d;
A c;
d.a=4;
c.a=5;
return d.a+c.a
}

ValeryS, покажи дамп этого. что получается на диске, плиз
Evg
Эксперт CАвтор FAQ
17292 / 5540 / 347
Регистрация: 30.03.2009
Сообщений: 15,083
Записей в блоге: 26
17.02.2012, 14:14     [C++] Взятие адреса конструктора. Физическое время существование объекта. #58
Цитата Сообщение от AzaKendler Посмотреть сообщение
про читерский метод мне подумалось что как ни крути а придется собрать бинарный файл и посмотреть таки дамп
Можно вообще ничего не смотреть. А исходить лишь из того, что мы знаем, как компилятор отманглирует имя конструктора

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
36
37
#include <stdio.h>
 
class A
{
    int a;
  public:
    A (int);
};
 
A::A (int x) : a(55555555 + x)
{
}
 
struct s
{
  int x;
};
 
/* Вот под таким именем будет в коде конструктор. На этапе разбора
 * конструкций языка, компилятор ещё не будет знать, что эта функция
 * на самом деле есть конструктор. Этот факт выяснится только на этапе
 * построения кода, когда вся языковые конструкции уже разобраны
 * и компилятор работает только с промежуточным представлением,
 * абстрагируясь от конкретного языка программирования */
extern "C" void _ZN1AC1Ei (struct s*, int);
 
int main (void)
{
  struct s str;
  str.x = 0;
 
  _ZN1AC1Ei (&str, 1);
 
  printf ("str.x=%d\n", str.x);
 
  return 0;
}
Цитата Сообщение от AzaKendler Посмотреть сообщение
выходит мы имеем просто функцию, которая лежит себе в сегменте кода, имеет определенный прототип и ей абсолютно все равно кого
инициализировать лишь бы подходил под прототип. так?
По сути да, но ограничение лишь бы подходило под прототип с точки зрения машинного кода лишнее. Можно вызвать и с другим прототипом. Но оно из-за этого может сломаться на исполнении (а может и не сломаться)

Цитата Сообщение от AzaKendler Посмотреть сообщение
и то это если функция "сложная" и компиллятор не решит обойтись вообще без нее.
Ворпроса не понял
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 14:25  [ТС]     [C++] Взятие адреса конструктора. Физическое время существование объекта. #59
Ворпроса не понял
Цитата Сообщение от ValeryS Посмотреть сообщение
mov edx,4
mov eax,5
add eax,edx
ret
я неправильно выразился. этот набор команд видимо может символизировать функцию в секции с кодом.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.02.2012, 19:03     [C++] Взятие адреса конструктора. Физическое время существование объекта.
Еще ссылки по теме:

C++ Зачем взятие адреса нулевого элемента массива, если сама переменная и так его содержит?
Получение адреса объекта после обнуления указателя на этот объект C++
C++ В чём отличия конструктора копирования и конструктора перемещения? Где и как их нужно использовать?
Используйте объект orange типа Tfruit для инициализации объекта grapefruit с помощью конструктора копирования C++
C++ Взятие значение из адреса

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

Или воспользуйтесь поиском по форуму:
ValeryS
Модератор
6482 / 4948 / 455
Регистрация: 14.02.2011
Сообщений: 16,389
18.02.2012, 19:03     [C++] Взятие адреса конструктора. Физическое время существование объекта. #60
Цитата Сообщение от AzaKendler Посмотреть сообщение
ValeryS, покажи дамп этого. что получается на диске,
немного поправил иначе вообще ничего не было
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "stdafx.h"
 
class A
{
public:
int a;
};
int fnk()
{
A b;
A c;
b.a=4;
c.a=5;
return b.a+c.a;
}
 
 
 
int _tmain(int argc, _TCHAR* argv[])
{
  
    return  fnk();
}
как я и предполагал
компилятор VS2008 оптимизация по умолчанию

Assembler
1
2
3
4
5
6
7
8
9
10
; int __cdecl main(int argc, const char **argv, const char **envp)
_main proc near
 
argc= dword ptr  4
argv= dword ptr  8
envp= dword ptr  0Ch
 
mov     eax, 9
retn
_main endp
смотри дамп сам
но учти что 99% там обвязка компилятора
как видишь оптимизатор выбросил все классы и даже функцию просто подсчитал результат
что еще раз подтверждает компиляция процесс не обратимый
Yandex
Объявления
18.02.2012, 19:03     [C++] Взятие адреса конструктора. Физическое время существование объекта.
Ответ Создать тему
Опции темы

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