J>Дело в том, что в этой новой функции надо будет указать параметры — такие же, как у конструктора. Ты устанешь всё это прописывать и поддерживать. J>А ещё — помню (смутно правда) стояла задача написать шаблон, чтобы для произвольного типа был некий класс, содержащий объект этого типа, и указатель. Ну чтобы связный список организовать. Я так и не додумался, как можно обеспечить передачу параметров в конструктор этого объекта. По-моему так дело обстояло.
Слушайте, что за глюк на сайте? Я сейчас добавил свои эти два сообщения. Открыты 2 вкладки браузера. В одной, я зашёл под своим аккаунтом, и в этом треде эти сообщения вижу. А в другой, открытой ранее, я не зашёл, и сообщений нет. Хотя и обновил страницу.
Здравствуйте, 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;
};
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, jamesq, Вы писали:
J>Дело в том, что в этой новой функции надо будет указать параметры — такие же, как у конструктора. Ты устанешь всё это прописывать и поддерживать. J>А ещё — помню (смутно правда) стояла задача написать шаблон, чтобы для произвольного типа был некий класс, содержащий объект этого типа, и указатель. Ну чтобы связный список организовать. Я так и не додумался, как можно обеспечить передачу параметров в конструктор этого объекта. По-моему так дело обстояло.
Здравствуйте, kov_serg, Вы писали:
_>Здравствуйте, jamesq, Вы писали:
J>>Дело в том, что в этой новой функции надо будет указать параметры — такие же, как у конструктора. Ты устанешь всё это прописывать и поддерживать. J>>А ещё — помню (смутно правда) стояла задача написать шаблон, чтобы для произвольного типа был некий класс, содержащий объект этого типа, и указатель. Ну чтобы связный список организовать. Я так и не додумался, как можно обеспечить передачу параметров в конструктор этого объекта. По-моему так дело обстояло.
_>
Ох уж этот новый C++ ...
Клёво конечно, но сколько ж можно всего изучать! У меня уже давно голова пухнет. Все кому не лень, налево и направо придумывают всякое, а ты давай учи!
J>Ох уж этот новый C++ ... J>Клёво конечно, но сколько ж можно всего изучать! У меня уже давно голова пухнет. Все кому не лень, налево и направо придумывают всякое, а ты давай учи!
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, jamesq, Вы писали:
J>>Ох уж этот новый C++ ... J>>Клёво конечно, но сколько ж можно всего изучать! У меня уже давно голова пухнет. Все кому не лень, налево и направо придумывают всякое, а ты давай учи!
_NN>Новы C++ вышел 8 лет назад если что
Я знаю. Я сейчас другими вещами занимаюсь, просто. Не C++
M>Чет мне кажется, что если ты и получишь адрес конструктора, то не факт, что компилятор не заинлайнит где-то вызов конструктора. Т.е. если ты его перехватишь (типа как перехватывается вызов методов в HippoMocks), то не факт, что перехватятся все вызовы конструктора.
Да есть такое, но этим можно управлять, например отключив оптимизацию прагмами.
Но в целом идея понятна. Единственное что попробую улучшить это написать дополнительную функцию для поиска call <адрес конструктора> в этой get_ctor_addr().
Здравствуйте, Pzz, Вы писали:
N>>По каким соображением в С++ запретили брать адрес конструктора, если по сути он есть обычная функция? N>>И есть ли возможность таки этот адрес получить?
Pzz>Потому, что с этим адресом нельзя сделать ничего полезного.
Ну да, конечно. Аллоцировать память через operator new(sizeof(Object)) и вызвать что ли нельзя? Вот указателя нет на конструктор, потому и нельзя. Но можно унаследоваться от класса, сделать функцию с тем же прототипом и запросто вызвать! Но вопрос, конечно, откуда взять адрес самого конструктора. Я делаю так:
1) в конструктор кладётся конструкция наподобии такой:
2) через __start_symbols и __stop_symbols можно перечислять экземпляры SymbolInstance, которые имеют функцию, которая берёт адрес &&__thunk и через dladdr(3) находит и замангленное имя конструктора, и его настоящий адрес.
3) при линковке нужен ключик -Wl,-E или что-то похожее, чтоб конструкторы попали в динамическую таблицу символов (иначе dladdr не заработает).
J>На мой взгляд, в конструкторах не хватает одной важной возможности. А именно — перед инициализацией полей и вызова конструктора базового класса (это то, что идёт после двоеточия), очень нужно бывает выполнить какой-нибудь код. Вычислить различные величины, например. Чтобы потом их скормить в этой инициализации.
Ну так в круглых скобочках в выражении BaseClass(...) можно записать любые вычисляющие выражения. Вызовы функций (для C++03) или вписать лямбду (для C++11).
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, 0x7be, Вы писали:
BFE>>>Не надо путать объект с местом для его размещения — это не одно и тоже. 0>>А в чем существенная разница в контексте заданного вопроса?
BFE>Зависит от того, что называть существенным. В С++ есть отдельный синтаксис для вызова конструктора с указанием места, где должен быть размещён объект. См. ответ kov_serg.
Можно с этого момента поподробней? Всегда считал, что конструктор это такая же функция, как и любая функция член класса...
Отдельный синтаксис (placement new?) к самому конструктору никак не относится, в конструктор тупо передаётся this так же как и в другие функции-члены.
BFE>Таким образом, для вызова конструктора через указатель нужен отдельный синтаксис.
Чем не устраивает синтаксис применяемый для других функций-членов класса?
BFE>Хотя всё это мелочи. Главный вопрос: зачем в рамках самого языка может понадобиться иметь такие указатели?
Проксировать вызовы внешних (из динамически загружаемой библиотеки) функций, например. Получается если конструктор в динамической библиотеке, то его не вызвать через dlsym(3), но вызвать если слинковать с библиотекой при компиляции. Где логика?
Здравствуйте, kov_serg, Вы писали:
J>>Дело в том, что в этой новой функции надо будет указать параметры — такие же, как у конструктора. Ты устанешь всё это прописывать и поддерживать. J>>А ещё — помню (смутно правда) стояла задача написать шаблон, чтобы для произвольного типа был некий класс, содержащий объект этого типа, и указатель. Ну чтобы связный список организовать. Я так и не додумался, как можно обеспечить передачу параметров в конструктор этого объекта. По-моему так дело обстояло.
_>
Функция конструктора всё равно должна быть непосредственно доступна в link time.
Не вариант для слуачая, когда конструктор находится в .so/.dll не доступной в момент линковки.
Здравствуйте, fk0, Вы писали:
fk0>Не вариант для слуачая, когда конструктор находится в .so/.dll не доступной в момент линковки.
Если конструктор находится в динамической библиотеке — вы сам себе злобный буратино. Только C апи, на крайняк COM.
Если вы экспортируете C++ апи наружу — значит "что-то пошло не так".
Здравствуйте, Pzz, Вы писали:
fk0>> Ну да, конечно. Аллоцировать память через operator new(sizeof(Object)) и вызвать что ли нельзя? Pzz>Для этого есть специальный синтаксис, placement new называется.
При использовании placement new символ конструктора адресуется компилятором напрямую. А хочется-то через указатель, т.е. не используя напрямую символ конструктора.
Здравствуйте, kov_serg, Вы писали:
fk0>>Не вариант для слуачая, когда конструктор находится в .so/.dll не доступной в момент линковки. _>Если конструктор находится в динамической библиотеке — вы сам себе злобный буратино. Только C апи, на крайняк COM. _>Если вы экспортируете C++ апи наружу — значит "что-то пошло не так".
Не вижу принципиальных проблем, если shared object будет линковаться в момент сборки.
Возможно есть какие-то corner cases неочевидные, но сходу не незвал бы.
Идиотические случаи (всё связанное с микрософтом и использование разных компиляторов) не рассматриваем.
Здравствуйте, fk0, Вы писали:
fk0> При использовании placement new символ конструктора адресуется компилятором напрямую. А хочется-то через указатель, т.е. не используя напрямую символ конструктора.
Я вот только не могу понять, к чему оно тебе такое хочется.