Re[3]: Адрес конструктора
От: jamesq Россия  
Дата: 14.07.19 04:59
Оценка:
Здравствуйте, jamesq, Вы писали:


J>Дело в том, что в этой новой функции надо будет указать параметры — такие же, как у конструктора. Ты устанешь всё это прописывать и поддерживать.

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

Слушайте, что за глюк на сайте? Я сейчас добавил свои эти два сообщения. Открыты 2 вкладки браузера. В одной, я зашёл под своим аккаунтом, и в этом треде эти сообщения вижу. А в другой, открытой ранее, я не зашёл, и сообщений нет. Хотя и обновил страницу.
Re[3]: Адрес конструктора
От: rg45 СССР  
Дата: 14.07.19 06:18
Оценка:
Здравствуйте, jamesq, Вы писали:

J>На мой взгляд, в конструкторах не хватает одной важной возможности. А именно — перед инициализацией полей и вызова конструктора базового класса (это то, что идёт после двоеточия), очень нужно бывает выполнить какой-нибудь код. Вычислить различные величины, например. Чтобы потом их скормить в этой инициализации.


Сейчас это легко делается при помощи делегирующих конструкторов:

class A
{
public:
  A(int a, int b) : A(a, b, double(a - b)/(a + b)) {}

private:

  A(int a, int b, double x) : a(a), b(b), c(x - 10), d(x * 20) {}

  int a;
  int b;
  double c;
  double d;   
};
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 15.07.2019 6:10 rg45 . Предыдущая версия .
Re[3]: Адрес конструктора
От: kov_serg Россия  
Дата: 14.07.19 07:25
Оценка:
Здравствуйте, jamesq, Вы писали:

J>Дело в том, что в этой новой функции надо будет указать параметры — такие же, как у конструктора. Ты устанешь всё это прописывать и поддерживать.

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

#include <cstddef>
#include <utility>

void* operator new(size_t size,void* where) { return where; }
template<class T,typename...Args> T* ctor(void *place,Args&&...args) { return new(place) T(std::forward<Args>(args)...); }
template<class T,typename...Args> char* get_ctor_addr() { return (char*)ctor<T,Args...>; }

struct A {
    A(){}
    A(int){}
    A(double){}
};

int main(int argc,char** argv) {
    char *p1=get_ctor_addr<A>();
    char *p2=get_ctor_addr<A,int>();
    char *p3=get_ctor_addr<A,double>();
    return 0;
}
Re[4]: Адрес конструктора
От: jamesq Россия  
Дата: 14.07.19 13:22
Оценка:
Здравствуйте, kov_serg, Вы писали:

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


J>>Дело в том, что в этой новой функции надо будет указать параметры — такие же, как у конструктора. Ты устанешь всё это прописывать и поддерживать.

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

_>
_>#include <cstddef>
_>#include <utility>

_>void* operator new(size_t size,void* where) { return where; }
_>template<class T,typename...Args> T* ctor(void *place,Args&&...args) { return new(place) T(std::forward<Args>(args)...); }
_>template<class T,typename...Args> char* get_ctor_addr() { return (char*)ctor<T,Args...>; }

_>struct A {
_>    A(){}
_>    A(int){}
_>    A(double){}
_>};

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

_>



Ох уж этот новый C++ ...
Клёво конечно, но сколько ж можно всего изучать! У меня уже давно голова пухнет. Все кому не лень, налево и направо придумывают всякое, а ты давай учи!
Re[5]: Адрес конструктора
От: _NN_ www.nemerleweb.com
Дата: 14.07.19 14:04
Оценка:
Здравствуйте, jamesq, Вы писали:


J>Ох уж этот новый C++ ...

J>Клёво конечно, но сколько ж можно всего изучать! У меня уже давно голова пухнет. Все кому не лень, налево и направо придумывают всякое, а ты давай учи!

Новы C++ вышел 8 лет назад если что
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: Адрес конструктора
От: jamesq Россия  
Дата: 14.07.19 21:19
Оценка:
Здравствуйте, _NN_, Вы писали:

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



J>>Ох уж этот новый C++ ...

J>>Клёво конечно, но сколько ж можно всего изучать! У меня уже давно голова пухнет. Все кому не лень, налево и направо придумывают всякое, а ты давай учи!

_NN>Новы C++ вышел 8 лет назад если что


Я знаю. Я сейчас другими вещами занимаюсь, просто. Не C++
Re[4]: Адрес конструктора
От: nen777w  
Дата: 15.07.19 13:37
Оценка:
M>Чет мне кажется, что если ты и получишь адрес конструктора, то не факт, что компилятор не заинлайнит где-то вызов конструктора. Т.е. если ты его перехватишь (типа как перехватывается вызов методов в HippoMocks), то не факт, что перехватятся все вызовы конструктора.

Да есть такое, но этим можно управлять, например отключив оптимизацию прагмами.
Re[7]: Адрес конструктора
От: _NN_ www.nemerleweb.com
Дата: 15.07.19 13:45
Оценка:
Здравствуйте, jamesq, Вы писали:

J>Я знаю. Я сейчас другими вещами занимаюсь, просто. Не C++


В других областях за 8 лет вообще всё устарело и надо учиться с нуля
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Адрес конструктора
От: nen777w  
Дата: 17.07.19 18:54
Оценка:
N>>И есть ли возможность таки этот адрес получить?
_>Нафига? Если сильно хочется сделайте функцию создающую экземпляр и используйте её адрес.

Для MSVC пришлось немного навернуть до:
struct dummy {};
void* operator new(size_t size, dummy, void* where) { return where; }
template<class T, typename ...TArg> T* ctor(void *place, TArg... args) { return new(dummy(), place) T(args...); }
template<class T, typename ...TArg> char* get_ctor_addr() { 
    decltype(&ctor<T, TArg...>) f = &ctor<T, TArg...>; 
    return reinterpret_cast<char*>(reinterpret_cast<void*&>(f)); 
}

struct A
{
    A();
};

struct B
{
    B(int);
};

char *pA = get_ctor_addr<A>();
char *pB = get_ctor_addr<B, int>();


Но в целом идея понятна. Единственное что попробую улучшить это написать дополнительную функцию для поиска call <адрес конструктора> в этой get_ctor_addr().
Отредактировано 17.07.2019 19:00 nen777w . Предыдущая версия .
Re[2]: Адрес конструктора
От: fk0 Россия https://fk0.name
Дата: 02.08.19 17:50
Оценка:
Здравствуйте, Pzz, Вы писали:

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

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

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


Ну да, конечно. Аллоцировать память через operator new(sizeof(Object)) и вызвать что ли нельзя? Вот указателя нет на конструктор, потому и нельзя. Но можно унаследоваться от класса, сделать функцию с тем же прототипом и запросто вызвать! Но вопрос, конечно, откуда взять адрес самого конструктора. Я делаю так:

1) в конструктор кладётся конструкция наподобии такой:

        __thunk:
        struct __Uniq {};
        static Thunk::SymbolInstance<__Uniq> __attribute__((section("symbols"))) __thunk(_LIB_, &&__thunk);


2) через __start_symbols и __stop_symbols можно перечислять экземпляры SymbolInstance, которые имеют функцию, которая берёт адрес &&__thunk и через dladdr(3) находит и замангленное имя конструктора, и его настоящий адрес.

3) при линковке нужен ключик -Wl,-E или что-то похожее, чтоб конструкторы попали в динамическую таблицу символов (иначе dladdr не заработает).
Re[3]: Адрес конструктора
От: fk0 Россия https://fk0.name
Дата: 02.08.19 17:52
Оценка:
Здравствуйте, jamesq, Вы писали:


J>На мой взгляд, в конструкторах не хватает одной важной возможности. А именно — перед инициализацией полей и вызова конструктора базового класса (это то, что идёт после двоеточия), очень нужно бывает выполнить какой-нибудь код. Вычислить различные величины, например. Чтобы потом их скормить в этой инициализации.


Ну так в круглых скобочках в выражении BaseClass(...) можно записать любые вычисляющие выражения. Вызовы функций (для C++03) или вписать лямбду (для C++11).
Re[6]: Адрес конструктора
От: fk0 Россия https://fk0.name
Дата: 02.08.19 17:59
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, 0x7be, Вы писали:


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

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

BFE>Зависит от того, что называть существенным. В С++ есть отдельный синтаксис для вызова конструктора с указанием места, где должен быть размещён объект. См. ответ kov_serg.


Можно с этого момента поподробней? Всегда считал, что конструктор это такая же функция, как и любая функция член класса...
Отдельный синтаксис (placement new?) к самому конструктору никак не относится, в конструктор тупо передаётся this так же как и в другие функции-члены.

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


Чем не устраивает синтаксис применяемый для других функций-членов класса?

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


Проксировать вызовы внешних (из динамически загружаемой библиотеки) функций, например. Получается если конструктор в динамической библиотеке, то его не вызвать через dlsym(3), но вызвать если слинковать с библиотекой при компиляции. Где логика?
Re[4]: Адрес конструктора
От: fk0 Россия https://fk0.name
Дата: 02.08.19 18:54
Оценка:
Здравствуйте, kov_serg, Вы писали:

J>>Дело в том, что в этой новой функции надо будет указать параметры — такие же, как у конструктора. Ты устанешь всё это прописывать и поддерживать.

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

_>
_>#include <cstddef>
_>#include <utility>

_>void* operator new(size_t size,void* where) { return where; }
_>template<class T,typename...Args> T* ctor(void *place,Args&&...args) { return new(place) T(std::forward<Args>(args)...); }
_>template<class T,typename...Args> char* get_ctor_addr() { return (char*)ctor<T,Args...>; }

_>struct A {
_>    A(){}
_>    A(int){}
_>    A(double){}
_>};

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

_>


Функция конструктора всё равно должна быть непосредственно доступна в link time.
Не вариант для слуачая, когда конструктор находится в .so/.dll не доступной в момент линковки.
Re[3]: Адрес конструктора
От: Pzz Россия https://github.com/alexpevzner
Дата: 02.08.19 23:07
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> Ну да, конечно. Аллоцировать память через operator new(sizeof(Object)) и вызвать что ли нельзя?


Для этого есть специальный синтаксис, placement new называется.
Re[5]: Адрес конструктора
От: kov_serg Россия  
Дата: 03.08.19 06:12
Оценка:
Здравствуйте, fk0, Вы писали:

fk0>Не вариант для слуачая, когда конструктор находится в .so/.dll не доступной в момент линковки.

Если конструктор находится в динамической библиотеке — вы сам себе злобный буратино. Только C апи, на крайняк COM.
Если вы экспортируете C++ апи наружу — значит "что-то пошло не так".
Re[4]: Адрес конструктора
От: fk0 Россия https://fk0.name
Дата: 03.08.19 08:58
Оценка:
Здравствуйте, Pzz, Вы писали:

fk0>> Ну да, конечно. Аллоцировать память через operator new(sizeof(Object)) и вызвать что ли нельзя?

Pzz>Для этого есть специальный синтаксис, placement new называется.

При использовании placement new символ конструктора адресуется компилятором напрямую. А хочется-то через указатель, т.е. не используя напрямую символ конструктора.
Re[6]: Адрес конструктора
От: fk0 Россия https://fk0.name
Дата: 03.08.19 09:04
Оценка:
Здравствуйте, kov_serg, Вы писали:

fk0>>Не вариант для слуачая, когда конструктор находится в .so/.dll не доступной в момент линковки.

_>Если конструктор находится в динамической библиотеке — вы сам себе злобный буратино. Только C апи, на крайняк COM.
_>Если вы экспортируете C++ апи наружу — значит "что-то пошло не так".

Не вижу принципиальных проблем, если shared object будет линковаться в момент сборки.
Возможно есть какие-то corner cases неочевидные, но сходу не незвал бы.

Идиотические случаи (всё связанное с микрософтом и использование разных компиляторов) не рассматриваем.
Re[5]: Адрес конструктора
От: Pzz Россия https://github.com/alexpevzner
Дата: 03.08.19 15:19
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> При использовании placement new символ конструктора адресуется компилятором напрямую. А хочется-то через указатель, т.е. не используя напрямую символ конструктора.


Я вот только не могу понять, к чему оно тебе такое хочется.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.