Адрес конструктора
От: nen777w  
Дата: 10.07.19 13:48
Оценка:
Добрый час!

По каким соображением в С++ запретили брать адрес конструктора, если по сути он есть обычная функция?
И есть ли возможность таки этот адрес получить?
Отредактировано 10.07.2019 13:49 nen777w . Предыдущая версия .
Re: Адрес конструктора
От: reversecode google
Дата: 10.07.19 14:06
Оценка: +2 -1
какой смысл копипастить вопросы со стек офервлова, не читая ответы там ?
как вы смогли так долго продержаться в ИТ игнорируя возможности поисковика гугл ?
Re: Адрес конструктора
От: rg45 СССР  
Дата: 10.07.19 15:22
Оценка: +3
Здравствуйте, nen777w, Вы писали:

N>По каким соображением в С++ запретили брать адрес конструктора, если по сути он есть обычная функция?

N>И есть ли возможность таки этот адрес получить?

В том-то и дело, что конструкторы — это не обычные функции, а специальные. Кострукторы не имеют имен, и используются только для инициализации объектов. Время жизни объекта начинается ПОСЛЕ выхода из конструктора. Другими словами, конструктор выполняется, когда время жизни объекта еще не началось и это принципиальное отличие — вызов конструктора для сконструированного объекта недопустим и невозможен (не путать с inplace конструированием, которое является инициализацией НОВОГО объекта с повторым использованием хранилища (storage)). В то же время указатели на функции-члены подразумевают использование с инициализированными объектами, что идет в разрез с требованиями, предъявляемыми к конструкторам.

15.1 Constructors
2 A constructor is used to initialize objects of its class type. Because constructors do not have names, they are never found during name lookup; however an explicit type conversion using the functional notation (8.2.3) will cause a constructor to be called to initialize an object. [ Note: For initialization of objects of class type see 15.6. —end note ]

--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 10.07.2019 18:08 rg45 . Предыдущая версия . Еще …
Отредактировано 10.07.2019 15:35 rg45 . Предыдущая версия .
Отредактировано 10.07.2019 15:24 rg45 . Предыдущая версия .
Отредактировано 10.07.2019 15:23 rg45 . Предыдущая версия .
Re: Адрес конструктора
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.07.19 15:59
Оценка: +1
Здравствуйте, nen777w, Вы писали:

N>По каким соображением в С++ запретили брать адрес конструктора, если по сути он есть обычная функция?

N>И есть ли возможность таки этот адрес получить?

Потому, что с этим адресом нельзя сделать ничего полезного.
Re: Адрес конструктора
От: B0FEE664  
Дата: 10.07.19 16:55
Оценка:
Здравствуйте, nen777w, Вы писали:

N>По каким соображением в С++ запретили брать адрес конструктора, если по сути он есть обычная функция?

Конструктор — это метод класса. Обычный метод класса для вызова требует иметь объект, для которого этот метод вызывается. Конструктор не нуждается в объекте для вызова, следовательно конструктор — не обычный метод класса.

N>И есть ли возможность таки этот адрес получить?

А вам зачем?
И каждый день — без права на ошибку...
Re: Адрес конструктора
От: _NN_ www.nemerleweb.com
Дата: 10.07.19 19:24
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Добрый час!


N>По каким соображением в С++ запретили брать адрес конструктора, если по сути он есть обычная функция?

Ну так и у функций класса получить адрес как бы не так просто получить.
Т.е. в определённых реализациях это будет возможно но в общем никак.

N>И есть ли возможность таки этот адрес получить?

Действительно стоит начать было тему с описанием зачем.
https://rsdn.org/Info/howtoask.xml#E3CAC
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Адрес конструктора
От: kov_serg Россия  
Дата: 10.07.19 20:23
Оценка: 4 (1) +1
Здравствуйте, nen777w, Вы писали:

N>Добрый час!


N>По каким соображением в С++ запретили брать адрес конструктора, если по сути он есть обычная функция?

Потому что в C++ много чего сделано через жопу. И это в том числе.

N>И есть ли возможность таки этот адрес получить?

Нафига? Если сильно хочется сделайте функцию создающую экземпляр и используйте её адрес.
#include <cstddef>

void* operator new(size_t size,void* where) { return where; }
template<class T> T* ctor(void *place) { return new(place) T(); }
template<class T> char* get_ctor_addr() { return (char*)&ctor<T>; }

struct A {
};

int main(int argc,char** argv) {
    char *p=get_ctor_addr<A>();
    return 0;
}
Re[2]: Адрес конструктора
От: nen777w  
Дата: 12.07.19 05:16
Оценка:
N>>По каким соображением в С++ запретили брать адрес конструктора, если по сути он есть обычная функция?
N>>И есть ли возможность таки этот адрес получить?

Pzz>Потому, что с этим адресом нельзя сделать ничего полезного.


А вот это не факт. Например мне понадобился этот адрес, и теперь нужно думать как это обойти.
Re[2]: Адрес конструктора
От: nen777w  
Дата: 12.07.19 05:21
Оценка:
N>>По каким соображением в С++ запретили брать адрес конструктора, если по сути он есть обычная функция?
BFE>Конструктор — это метод класса. Обычный метод класса для вызова требует иметь объект, для которого этот метод вызывается. Конструктор не нуждается в объекте для вызова, следовательно конструктор — не обычный метод класса.

Да, но по сути это обычная функция (если рассматривать ее со стороны ассемблера).

N>>И есть ли возможность таки этот адрес получить?

BFE>А вам зачем?

Если кратко, это связано с самописным протектором который я использую в своем приложении.
Вот другая моя тема с этим связанная: http://rsdn.org/forum/asm/7487846
Автор: nen777w
Дата: 06.07.19
Re[2]: Адрес конструктора
От: nen777w  
Дата: 12.07.19 05:22
Оценка:
N>>И есть ли возможность таки этот адрес получить?
_>Нафига? Если сильно хочется сделайте функцию создающую экземпляр и используйте её адрес.

Спасибо. Проверю.
Re[3]: Адрес конструктора
От: B0FEE664  
Дата: 12.07.19 08:22
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Да, но по сути это обычная функция (если рассматривать ее со стороны ассемблера).

Вообще говоря такой гарантии нет. Простейщий вариант — это inline конструктор.

N>>>И есть ли возможность таки этот адрес получить?

BFE>>А вам зачем?
N>Если кратко, это связано с самописным протектором который я использую в своем приложении.
N>Вот другая моя тема с этим связанная: http://rsdn.org/forum/asm/7487846
Автор: nen777w
Дата: 06.07.19


Вряд ли я с этим смогу помочь, могу только сказать, что конструктор класса можно сделать приватным, а создание с помощью static функции, адрес которой можно взять:

class A
{
  private:
    A(){}
  public:
    static A* CreateA() { return new A(); }
    void Foo() {std::cout << "A::Foo()\n";}
};

int main()
{
  A* (*pFn)() = &A::CreateA;
  A* p = pFn();
  p->Foo();

  std::cout << "ok\n";
  return 0;
}


http://ideone.com/gxQ7DX
И каждый день — без права на ошибку...
Re[2]: Адрес конструктора
От: 0x7be СССР  
Дата: 12.07.19 08:29
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Конструктор не нуждается в объекте для вызова

Если я правильно помню, то конструктор не выделяет память для объекта, указатель на область памяти, которую он должен инициализировать он получает извне.
Так что данное утверждение — ложно.
Re[3]: Адрес конструктора
От: B0FEE664  
Дата: 12.07.19 08:48
Оценка:
Здравствуйте, 0x7be, Вы писали:

BFE>>Конструктор не нуждается в объекте для вызова

0>Если я правильно помню, то конструктор не выделяет память для объекта, указатель на область памяти, которую он должен инициализировать он получает извне.
0>Так что данное утверждение — ложно.

Не надо путать объект с местом для его размещения — это не одно и тоже.
И каждый день — без права на ошибку...
Re[4]: Адрес конструктора
От: 0x7be СССР  
Дата: 12.07.19 08:57
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Не надо путать объект с местом для его размещения — это не одно и тоже.

А в чем существенная разница в контексте заданного вопроса?
Re[5]: Адрес конструктора
От: B0FEE664  
Дата: 12.07.19 10:19
Оценка:
Здравствуйте, 0x7be, Вы писали:

BFE>>Не надо путать объект с местом для его размещения — это не одно и тоже.

0>А в чем существенная разница в контексте заданного вопроса?

Зависит от того, что называть существенным. В С++ есть отдельный синтаксис для вызова конструктора с указанием места, где должен быть размещён объект. См. ответ kov_serg.
То, что синтаксис особый — это не просто так.
Допустим у нас есть возможность взять адрес конструктора, тогда вызов такого конструктора через указатель должен выглядеть как-то так:
class A
{
  public:
   A(){}
};

auto p = &A::A; // если не auto, то что?

char buf[sizeof A]; // игнорируем проблему выравнивания

(buf->*p)();             // странно как-то, у char есть метод ?
(((void*)(buf))->*p)();  // у void есть метод?
(buf.*p)();              // как-то странно...



Таким образом, для вызова конструктора через указатель нужен отдельный синтаксис. Т.е. у нас получится ещё одно семейство указателей с ещё и специфическим синтаксисом вызова этих указателей. А весь выигрыш будет состоять только в том, что вместо new (buf) A; можно будет написать new (buf) p; например.

Хотя всё это мелочи. Главный вопрос: зачем в рамках самого языка может понадобиться иметь такие указатели? Вне языка, как у топикастера, это понятно, но стоит ли ради таких специфичных задач менять сам язык?
И каждый день — без права на ошибку...
Re[3]: Адрес конструктора
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.07.19 11:28
Оценка:
Здравствуйте, nen777w, Вы писали:

Pzz>>Потому, что с этим адресом нельзя сделать ничего полезного.


N>А вот это не факт. Например мне понадобился этот адрес, и теперь нужно думать как это обойти.


Зачем, интересно, он мог тебе понадобиться?
Re[6]: Адрес конструктора
От: 0x7be СССР  
Дата: 12.07.19 13:42
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Таким образом, для вызова конструктора через указатель нужен отдельный синтаксис. Т.е. у нас получится ещё одно семейство указателей с ещё и специфическим синтаксисом вызова этих указателей. А весь выигрыш будет состоять только в том, что вместо new (buf) A; можно будет написать new (buf) p; например.

Не обязательно нужен новый синтаксис, это решаемые вопросы.

BFE>Хотя всё это мелочи. Главный вопрос: зачем в рамках самого языка может понадобиться иметь такие указатели? Вне языка, как у топикастера, это понятно, но стоит ли ради таких специфичных задач менять сам язык?

Это хороший вопрос. Скорее всего, топикстартеру тоже нужно не совсем то, что может ему дать ссылка на конструктор. Скорее всего он имеет в виду что-то типа виртуальной фабрики класса.
Re[3]: Адрес конструктора
От: Masterspline  
Дата: 13.07.19 00:19
Оценка:
N>>>И есть ли возможность таки этот адрес получить?
BFE>>А вам зачем?

N>Если кратко, это связано с самописным протектором который я использую в своем приложении.


Чет мне кажется, что если ты и получишь адрес конструктора, то не факт, что компилятор не заинлайнит где-то вызов конструктора. Т.е. если ты его перехватишь (типа как перехватывается вызов методов в HippoMocks), то не факт, что перехватятся все вызовы конструктора.
Re[2]: Адрес конструктора
От: jamesq Россия  
Дата: 14.07.19 04:47
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, nen777w, Вы писали:


N>>По каким соображением в С++ запретили брать адрес конструктора, если по сути он есть обычная функция?

N>>И есть ли возможность таки этот адрес получить?

R>В том-то и дело, что конструкторы — это не обычные функции, а специальные. Кострукторы не имеют имен, и используются только для инициализации объектов. Время жизни объекта начинается ПОСЛЕ выхода из конструктора. Другими словами, конструктор выполняется, когда время жизни объекта еще не началось и это принципиальное отличие — вызов конструктора для сконструированного объекта недопустим и невозможен (не путать с inplace конструированием, которое является инициализацией НОВОГО объекта с повторым использованием хранилища (storage)). В то же время указатели на функции-члены подразумевают использование с инициализированными объектами, что идет в разрез с требованиями, предъявляемыми к конструкторам.


R>

R>15.1 Constructors
R>2 A constructor is used to initialize objects of its class type. Because constructors do not have names, they are never found during name lookup; however an explicit type conversion using the functional notation (8.2.3) will cause a constructor to be called to initialize an object. [ Note: For initialization of objects of class type see 15.6. —end note ]


На мой взгляд, в конструкторах не хватает одной важной возможности. А именно — перед инициализацией полей и вызова конструктора базового класса (это то, что идёт после двоеточия), очень нужно бывает выполнить какой-нибудь код. Вычислить различные величины, например. Чтобы потом их скормить в этой инициализации.
Re[2]: Адрес конструктора
От: jamesq Россия  
Дата: 14.07.19 04:52
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, nen777w, Вы писали:


N>>Добрый час!


N>>По каким соображением в С++ запретили брать адрес конструктора, если по сути он есть обычная функция?

_>Потому что в C++ много чего сделано через жопу. И это в том числе.

N>>И есть ли возможность таки этот адрес получить?

_>Нафига? Если сильно хочется сделайте функцию создающую экземпляр и используйте её адрес.
_>
_>#include <cstddef>

_>void* operator new(size_t size,void* where) { return where; }
_>template<class T> T* ctor(void *place) { return new(place) T(); }
_>template<class T> char* get_ctor_addr() { return (char*)&ctor<T>; }

_>struct A {
_>};

_>int main(int argc,char** argv) {
_>    char *p=get_ctor_addr<A>();
_>    return 0;
_>}
_>


Дело в том, что в этой новой функции надо будет указать параметры — такие же, как у конструктора. Ты устанешь всё это прописывать и поддерживать.
А ещё — помню (смутно правда) стояла задача написать шаблон, чтобы для произвольного типа был некий класс, содержащий объект этого типа, и указатель. Ну чтобы связный список организовать. Я так и не додумался, как можно обеспечить передачу параметров в конструктор этого объекта. По-моему так дело обстояло.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.