Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.06.2012, 23:41   #11
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

rmv240899 верно говорит.
насколько мне известно, для базовых типов такая запись введена только для поддержки обобщенного программирования на шаблонах, чтобы код компилился независимо от типа
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 28.06.2012, 00:01   #12
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
а что, балет?
Значит по твоему atoi() тоже является функцией преобразования типов?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 28.06.2012, 00:01   #13
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

де-факто это конструктор(как и говорит pproger), на практике выходит приведение типов.

почему важно это помнить, ибо с другим типом это будет уже конструктор.
Цитата:
Можно записать и так
И результат будет тот же.
да, но это уже приведение в стиле С.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 28.06.2012, 08:54   #14
Krok27
Форумчанин
 
Аватар для Krok27
 
Регистрация: 08.07.2010
Сообщений: 505
По умолчанию

Код:
int y;
y=int(x);
Вне обобщенного программирования - приведение типов.

В обобщенном такой записи не встречал, тока

Код:
template <class T>
////////////////////
//в конструкторе:
y=T();
без параметров. Гарантия инициализации переменной начальным значением (обычно 0) для базовых типов или вызова конструктора по умолчанию для производных.
Знающий не говорит, говорящий не знает (С) Лао Цзы
Krok27 вне форума Ответить с цитированием
Старый 28.06.2012, 20:37   #15
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от rmv240899 Посмотреть сообщение
_Bers, для базовых типов данных не вызываются конструкторы, и уж тем более operator=. int(x) это форма записи С-оператора приведения типа. Я откомпилировала код, именно на С++:
Код и результат
Смотри, запись вида:

Код:
int(10);
Синтаксически это именно вызов конструктора с параметром.

По стандарту плюсов, запись вида: Имя_типа(аргументы), является запуском конструктора с параметрами, и результатом выражения будет являться объект. Это справедливо для любых типов на языке с++. В том числе и для примитивных.

Другое дело, что пофакту, примитивные типы, такие, как инт не обладают конструкторами в том виде, в каком ими обладают конструкторы классов.

От int нельзя унаследоваться. А конструкторы инта по дефолту - "как бы ничего не делают", либо инициализируют объект значением.

Само понятие "конструктора" для примитивного типа данных по сути является лишь синтаксическим сахаром для поддержания единообразного синтаксиса работы с простыми и пользовательскими типами с++, при сохранении обратной совместимости этих типов с си-типами.

Программист пишет запись:

Код:
int(10);  //запускаю конструктор объекта с параметром. 
            //Хочу получить временный объект
можно написать так:

Код:
int a(10);  //создаю объект, запустив конструктор с параметром
Что именно вместо этой записи на самом деле будет произведено/подставлено компилятором, и как он будет оптимизировать данную процедуру - его персональная головная боль.

Программиста на с++ не интересует, во что именно превратится код после компиляции.

Программиста на с++ интересует, что он ожидает получить объект, и он его получит. Мутки компилятора - его личные сложности.


Я могу написать вот так:

Код:
 CSomeClass(arg); //ты хочешь сказать,
      // что это тоже "форма приведения в стиле языка си? "

На плюсах, приведение в стиле си - синтаксический сахар над запуском конструкторов.

Запись вида:
Код:
(int) val;
эквивалентна записи вида:

Код:
int(val);
Если не считать того, что сишное приведение не оперирует понятиеми классов, и конструкторов. А так же того, что при сишном приведении двух объектов сработает конструктор


Ну и самое главное: "преобразование типа" - процедура в результате которой нечто становится преобразованным (модифицированным).

Приведение в стиле си на плюсах приводит к запускам конструкторов и созданию принципиально новых объектов. В результате процедуры создаётся новый объект. А старый остаётся таким же, как был.
Поскольку оригинальный объект не преобразовывается (не модифицируется), то приведение в стиле си на плюсах не является процедурой преобразования типа объекта к другому типу.

Последний раз редактировалось _Bers; 28.06.2012 в 20:41.
_Bers вне форума Ответить с цитированием
Старый 28.06.2012, 22:46   #16
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Цитата:
По стандарту плюсов, запись вида: Имя_типа(аргументы), является запуском конструктора с параметрами, и результатом выражения будет являться объект. Это справедливо для любых типов на языке с++. В том числе и для примитивных.
В пункте 5.2.3 стандарта это называется Explicit type conversion (functional notation). Там написано
Цитата:
If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).
Далее, если я нигде не ошибся, по ссылкам это сводится (в случае с int) к static_cast, потом к объявлению с инициализацией. Никаких конструкторов не вижу...
Somebody вне форума Ответить с цитированием
Старый 29.06.2012, 00:58   #17
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Somebody Посмотреть сообщение

Далее, если я нигде не ошибся, по ссылкам это сводится (в случае с int) к static_cast, потом к объявлению с инициализацией. Никаких конструкторов не вижу...
Может быть ты просто плохо смотришь?

Код:
struct SBase
{
    SBase() { std::cout<<"create base\n"; }
    SBase(const SBase& src) { std::cout<<"copy base\n"; }
};

struct SDerrived:public SBase
{
    SDerrived(): SBase() { std::cout<<"create derrived\n"; }
    SDerrived(const SDerrived& src ) { std::cout<<"copy derrived\n"; }
};

int main()
{

    SDerrived derrived;

    SBase agent = static_cast<SBase>(derrived);
  
     return 0;
}

Синтаксис с++ организован таким образом, что бы можно было единообразно работать с любыми типами данных.

Механика приведение типа на с++ такова, что приводит к созданию копии сущности, а не к преобразованию типа существующего имени объекта.

В ряде случаев эта процедура успешно может быть оптимизирована (и тогда можно будет избежать запуска "лишних" копирующих конструкторов).

А в некоторых случаях компиляторы обязаны суметь оптимизировать.

Но в общем и в целом, сама языковая механика приведения типов является одинаковой для любых типов данных: и примитивных, и классов.

Если бы для разных типов применялись бы разные правила синтаксиса, тогда не просто язык был бы неоправданно сложнее раз этак в сто.

Но и написание самого тривиального шаблона бы требовало особых знаний метапрограммирования, и километр нетривиального шаблонистого кода.


Даже если в качестве приведения использовать не объект по значению, а объект по ссылке - то все равно будет запущен конструктор и будет создана копия (ссылки естественно).

А вот наличие/отсутствие конструкторов у примитивных типов по факту - программиста на с++ уже не интересует.

Ему достаточно этой единообразной для любых типоф данных информации, что бы понимать - приведение типов всегда запускает конструктор.

И программист на с++ знает, что копирование простого указателя или ссылки дешевле, чем копирование целого тяжелого объекта.

И поэтому, если программисту на с++ нужно изменить интерпретацию объекта (сменить тип имени, по которому осуществляется доступ к объекту), то он будет приводить не тип самого объекта по значению, а тип указателя или ссылки на него, что бы избежать напрасного копирующего конструктора тяжелого объекта.


Поэтому, если ты программируешь на с++, то всегда имей ввиду: приплюснутое приведение типов, или сишное приведение типов на яыке с++ это не преобразования типа самого имени, по которому осуществляется доступ к объекту. Это - всегда запуск конструктора, и создания временной копии объекта, который участвовал в операции приведения типа.
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
<< >> & ^ | с чем это едят и что это такое? pufystyj Общие вопросы C/C++ 4 30.03.2011 13:59
Эквалайзер...что это? кто это? Можно ли с ним подружиться? .Phoenix Мультимедиа в Delphi 45 08.04.2010 23:37
Что это такое и как это того... Alex Cones Общие вопросы Delphi 2 11.10.2009 12:04