Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

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

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

16.02.2012, 15:40. Просмотров 8910. Ответов 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;
};
каково время жизни поля класса после уничтожения объекта класса?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.02.2012, 15:40
Здравствуйте! Я подобрал для вас темы с ответами на вопрос [C++] Взятие адреса конструктора. Физическое время существование объекта. (C++):

Почему лучше инициализировать объекты класса во время инициализации конструктора? - C++
Имеется класс Rnd: class Rnd { public: Rnd::Rnd(int x); private: int val; };

Взятие значение из адреса - C++
Имеется код добавления объекта &quot;точка&quot; в массив точек: void arr_point::add_point(point &amp;p) { point *buf = new point;//Создаю...

Взятие адреса в аргументе - C++
Есть такой код: void STOCK::acquiare(const std::string &amp;co,long n, double pr) { company=co; if (n&lt;0) { ...

Взятие адреса у константной переменной при объявлении - C++
Можно пример?

Зачем взятие адреса нулевого элемента массива, если сама переменная и так его содержит? - C++
Доброго времени суток. Очень часто наблюдаю во всевозможных примерах такого вида код: void* bits = (void*)&amp;(pixels); Таких...

[Двусвязные списки] Добавление по индексу. Взятие адреса по индексу - C++
По заданию требуется: 1) Создать функцию void Insert(Person&amp; person, int index), помещающую переменную типа Person по указанному...

69
silent_1991
Эксперт С++
4993 / 3051 / 149
Регистрация: 11.11.2009
Сообщений: 7,038
Завершенные тесты: 1
16.02.2012, 21:14 #31
AzaKendler, не-а, не нахожу. Вызов a.foo() разворачивается в foo(&a). this и есть тот указатель (являющийся неявным параметром любого нестатического метода класса), который содержит адрес вызывающего объекта.
1
Evg
Эксперт CАвтор FAQ
18449 / 6499 / 454
Регистрация: 30.03.2009
Сообщений: 18,129
Записей в блоге: 29
16.02.2012, 21:14 #32
AzaKendler, уж не раз отсылал тебя к своей статье, почему-то не хочешь читать, хотя все ответы на твои вопросы там есть

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class A
{
  public:
    int a;
 
    A() : a(555) {}
    ~A() {}
};
 
int main()
{
  A* pa = &A();
}
эквивалентно

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
/* Вот так выглядит экземпляр класса в памяти */
struct A
{
  int a;
};
 
/* Конструктор */
void A_constr (struct A *this)
{
  this->a = 555;
}
 
/* Деструктор */
void A_destr (struct A *this)
{
}
 
int main (void)
{
  /* Эти две строки есть эквивалент кода "A()" */
  tmp_A;
  A_constr (&tmp_A);
 
  /* А эта строка в совокупности с двумя предыдущими есть
   * эквивалент кода "A *pa = &A();" */
  A *pa = &tmp_A;
}
Указатель pa смотрит на фрагмент стека, куда компилятор распределил временный объект. От этого куска стека ты никак не можешь попасть до того реального места, где у тебя лежит процедура, соответствующая конструктору.

Если теперь откомпилировать программу на Си++ и посмотреть на код:

Код
$ g++ t.cc -c
t.cc: In function 'int main()':
t.cc:12: warning: taking address of temporary
Код
$ readelf --symbols t.o

Symbol table '.symtab' contains 16 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
...
    12: 00000000    14 FUNC    WEAK   DEFAULT    7 _ZN1AC1Ev
...
    14: 00000000     5 FUNC    WEAK   DEFAULT    8 _ZN1AD1Ev
    15: 00000000    48 FUNC    GLOBAL DEFAULT    3 main
Функция _ZN1AC1Ev соответствует конструктору, функция _ZN1AD1Ev - деструктору. Чтобы такие кривые (манглированные) имена переводить в божеский вид, можно воспользоватся утилитой c++filt:

Код
$ c++filt _ZN1AC1Ev
A::A()
$ c++filt _ZN1AD1Ev
A::~A()
2
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
16.02.2012, 21:52  [ТС] #33
Указатель pa смотрит на фрагмент стека, куда компилятор распределил временный объект. От этого куска стека ты никак не можешь попасть до того реального места, где у тебя лежит процедура, соответствующая конструктору.


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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
struct A
{
 void test(){int a =56;int b =4; int c =a+b;}
}
 
int main()
{
A a;
A* pa = &a;//указывает на секцию с данными на начало "a",верно?
pa->test();  //вызов возможен.
pa->~A; //тоже
 
}
где же лежит конструктор? в "особом" месте?
0
Evg
Эксперт CАвтор FAQ
18449 / 6499 / 454
Регистрация: 30.03.2009
Сообщений: 18,129
Записей в блоге: 29
16.02.2012, 22:02 #34
Ау!! Ты вообще читаешь, что тебе пишут? Конструктор с точки зрения кода это САМАЯ ОБЫЧНАЯ ФУНКЦИЯ.

Цитата Сообщение от AzaKendler Посмотреть сообщение
а из этого места я могу попасть туда где лежат другие процедуры и деструктор например?
Создай локал "int x;" в функции main, возьми на "x" адрес. Как из "этого места" ты можешь "попасть туда, где лежат другие функции (например, func)". Очевидно, что никак

Цитата Сообщение от AzaKendler Посмотреть сообщение
что это означает? конструктор что лежит в "особом" месте?
Ещё раз. Конструктор - это ОБЫЧНАЯ ФУНКЦИЯ и лежит она там, где лежат все остальные функции

Цитата Сообщение от AzaKendler Посмотреть сообщение
где же лежит конструктор? в "особом" месте?
См. выше
0
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
16.02.2012, 22:05  [ТС] #35
Evg, ну это понятно. тогда его вызов извне ограничен только в контексте языка с++ и концепции классов я прав?
и теоретически мы можем вызвать конструктор, поскольку он является обычной функцией найдя его адрес в загруженном в память файле. верно? я имею ввиду следующее - загрузили файл, нашли адрес его модуля, допустим мы знаем смещение до такой функции как конструктор и найдя ее адрес в памяти обращаемся к ней минуя высокоуровневые конструкции
0
Evg
Эксперт CАвтор FAQ
18449 / 6499 / 454
Регистрация: 30.03.2009
Сообщений: 18,129
Записей в блоге: 29
16.02.2012, 22:11 #36
Цитата Сообщение от AzaKendler Посмотреть сообщение
Evg, ну это понятно. тогда его вызов извне ограничен только в контексте языка с++ и концепции классов я прав?
Именно так. Точно так же ты можешь "вызвать" переменную. Правда засада может быть в том, что переменные складываются в страницы памяти, в которых операционная системе не разрешает исполнять код, но это всё рулится (под линуксом через mprotect)

C
1
2
3
4
5
6
7
8
/* Тут как бы рисуем код */
char c[] = { 0x11, 0x22, 0x33, .... }
 
int main (void)
{
  mprotect ( /* лень разбираться, что конкретно тут подавть надо */); */
  ((void(*)(void)) &c)();
}
1
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
16.02.2012, 22:14  [ТС] #37
Evg, спасибо. и последний вопрос.
0
Bers
Заблокирован
16.02.2012, 22:17 #38
Evg, как на с++ можно заполучить адрес конструктора, и запустить его по "указателю" ?
0
Evg
Эксперт CАвтор FAQ
18449 / 6499 / 454
Регистрация: 30.03.2009
Сообщений: 18,129
Записей в блоге: 29
16.02.2012, 22:21 #39
Цитата Сообщение от Bers Посмотреть сообщение
Evg, как на с++ можно заполучить адрес конструктора, и запустить его по "указателю" ?
Я плохо разбираюсь в Си++, но, насколько знаю, адрес конструктора средствами языка взять нельзя
0
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
16.02.2012, 22:25  [ТС] #40
Цитата Сообщение от Evg Посмотреть сообщение
адрес конструктора средствами языка взять нельзя
из текущего модуля в котором и пишется класс. а из загруженного файла функциями api все что угодно. надо только понять где конструктор в образе файла. и тогда получится вызов констуктора как простой функции из языка с++, средствами с++, но...не в том файле в котором писался искомый класс
0
Evg
Эксперт CАвтор FAQ
18449 / 6499 / 454
Регистрация: 30.03.2009
Сообщений: 18,129
Записей в блоге: 29
16.02.2012, 22:27 #41
Цитата Сообщение от AzaKendler Посмотреть сообщение
а из загруженного файла функциями api все то угодно
Я же говорил, что "средствами языка". Ковыряясь в бинарном файле или используя всякие сторонние средства можно сделать всё, что угодно. Так или иначе вся защищённость Си++ - она только на уровне языка программирования, но не на уровне бинарного кода. Об этом я писал здесь: Функции класса в разделе private реализуются так же как и в разделе public?

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

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

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


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

например

C++
1
2
3
class A;
char buf[100];
A* pa = new(buf) A;// сконструировать конструктором в уже готовой области
здесь не оно? не чисто конструктор вызовется? Если нет то поясни процесс создания немного плиз.
0
ValeryS
Модератор
6745 / 5154 / 492
Регистрация: 14.02.2011
Сообщений: 17,324
16.02.2012, 23:49 #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
напиши простейшую программу и компильни в трех вариантах
дебиг
релиз с отладочной информацией
релиз без отладочной информации
и дизасемблируй
в третьем варианте даже имен не будет

например в моем примере даже конструктора не будет
выделится память и все
соответственно что искать
если есть виртуальные функции то может быть можно получить указатель на таблицу виртуальных функций(хотя маловероятно) а потом прсканировать память и найти кто считывает этот адрес и записывает в себя, это и есть конструктор ( а так же деструктор), но как это реализовать я не знаю
1
Evg
Эксперт CАвтор FAQ
18449 / 6499 / 454
Регистрация: 30.03.2009
Сообщений: 18,129
Записей в блоге: 29
16.02.2012, 23:55 #44
Цитата Сообщение от AzaKendler Посмотреть сообщение
что означает создать объект растолкуй
Ты статью читал? Просто мне уже интересно, то читал, но не понял или не читал? Потому как все эти вопросы там описывались

Добавлено через 1 минуту
В посте 32 то же самое расписывал. Ты никак не можешь понять одну простую вещь: правильно поставленный вопрос - это уже половина ответа. А ворох разнообразных ответов говорит о том, что вопрос поставлен невнятно и каждый ответивший понимает его по своему. Я, если честно, не могу понять, что тебе не понятно
0
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 08:59  [ТС] #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;
}
прокомментируй пожалуйста эти три случая. просто на пальцах. хочу четкого понимания.
0
17.02.2012, 08:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.02.2012, 08:59
Привет! Вот еще темы с ответами:

Существование объекта - C++
Здравствуйте, есть довольно сложное и интересное задание Есть класс someClass нужно сделать так чтобы: 1) Его объекты можно было...

Проверка на существование proxy адреса - Visual Basic
Добрый день У меня такой вопрос Каким кодом я могу осуществить проверку на существование proxy адреса на работоспособность. Допустим...

Проверка URL адреса на существование - VBA
Доброго времени суток! Есть определенный цикл по перебору страниц сайта, цикл определяет некоторые недоступные страницы вследствие их...

Проверить существование объекта - C++ Qt
Есть QList&lt;QTcpSocket*&gt; _psocks. Все сокеты, которые попадают в этот список проходят через соединение: connect(psock,...


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

Или воспользуйтесь поиском по форуму:
45
Ответ Создать тему
Опции темы

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