Форум программистов, компьютерный форум CyberForum.ru

Объясните неявное преобразование в этом случае - C++

Восстановить пароль Регистрация
 
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
15.02.2013, 13:04     Объясните неявное преобразование в этом случае #1
C++
1
scoped_ptr p = new Object();
То есть "p" неявно преобразовывается в указатель, но как не понятно. Это я встретил просматривая вот это. В коментариях был ответ "scoped_ptr p = new Object();
Здесь работает неявное преобразование. У scoped_ptr в конструкторе указан аргументом Object*, справа от знака "=" как раз такой указатель и создаётся.
Компилятор в таком случае преобразует эту конструкцию к scoped_ptr p(new Object());
т.е. такой вызов эквивалентен вызову конструктора. За подробностями надо гуглить по ключевому слову explicit".
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
15.02.2013, 13:46     Объясните неявное преобразование в этом случае #2
mzarb, нет, создается объект p и в его конструктор передается агрумент - Object*
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
15.02.2013, 16:26  [ТС]     Объясните неявное преобразование в этом случае #3
Kgfq, но лектор дальше использует этот объект "p" как указатель. И называет его с самого начала указателем, а не объектом.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
15.02.2013, 17:08     Объясните неявное преобразование в этом случае #4
mzarb, я не понимаю, тут чтото не то:
1) у boost::scoped_ptr конструктор - explicit - это как раз обозначает, что конструкции вида boost::scoped_ptr = new Object() как раз работать не должны
2) я всю жизнь думал, что дедукция типов в шаблоне работает только для функций, для классов так работать не будет
3) ну у меня лично не компилируется подобный код (если Object ни от чего хитрого не унаследован, или что-нибудь еще в этом роде)

C++
1
2
3
4
5
6
7
8
9
#include <boost/scoped_ptr.hpp>  
 
class A {
 
};
 
int main () {
    boost::scoped_ptr p = new A;
}
Bash
1
2
3
4
5
alex@ubuntu:~/c++$ g++ sc.cpp 
sc.cpp: In function ‘int main()’:
sc.cpp:8:23: error: missing template arguments before ‘p’
sc.cpp:8:23: error: expected ‘;’ before ‘p’
alex@ubuntu:~/c++$ 3~
Добавлено через 33 минуты
Цитата Сообщение от mzarb Посмотреть сообщение
Kgfq, но лектор дальше использует этот объект "p" как указатель. И называет его с самого начала указателем, а не объектом.
это нормально, у scoped_ptr перегружены операторы -> и *, так что тут поведение такое же как и у всех умных указателей
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
15.02.2013, 18:28     Объясните неявное преобразование в этом случае #5
В видео по той ссылке там свой scoped_ptr, а не из Boost, и там нет ни шаблонов, ни explicit.
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
15.02.2013, 19:17     Объясните неявное преобразование в этом случае #6
Цитата Сообщение от mzarb Посмотреть сообщение
То есть "p" неявно преобразовывается в указатель, но как не понятно.
этот
Цитата Сообщение от mzarb Посмотреть сообщение
C++
1
scoped_ptr p = new Object();
код эквивалентен следующему коду:
C++
1
scoped_ptr p(scoped_ptr(new Object());
чтобы избежать подобного оверхеда и ввели explicit, а затем и move semantics
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
16.02.2013, 12:13  [ТС]     Объясните неявное преобразование в этом случае #7
Jupiter, Спасибо. То есть можно правую часть присвоить левой потому, что когда запустится конструткор scoped_ptr, то тип его параметра будет приведен к типу класса, а так как параметр в этом конструкторе был указатель на объект класса Object, то при создании объектов будет срабатывать привидение типов с неявным преобразованием объектов в указатели, потому как с левой стороны будет адресс и с правой нужен указатель чтобы его хранить, а не объект. А если написать так
C++
1
scoped_ptr p(scoped_ptr(new Object());
, то будет не указатель, а объект. Но а что понимается под оверхедом, то что приведение типов вызывает накладные ресурсы?
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
16.02.2013, 12:21     Объясните неявное преобразование в этом случае #8
Цитата Сообщение от mzarb Посмотреть сообщение
Но а что понимается под оверхедом, то что приведение типов вызывает накладные ресурсы?
сначало конструируется scoped_ptr(new Object()), который затем передается в конструктор копирования, который вызыватся для р т.е. вызывается два конструктора, когда вполне можно обойтись одним.
"умный" компилятор может оптимизировать этот код и убрать вызов конструктора копирования, но может и не убрать.
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
16.02.2013, 21:34  [ТС]     Объясните неявное преобразование в этом случае #9
Jupiter, наверное я не могу это понять потому, что забыл как работает приведение типов. То есть чтобы привести объект к какому-то типу, должна создатся его копия и такой код
C++
1
scoped_ptr p(scoped_ptr(scoped_ptr(scoped_ptr(new Object()))));
должен будет запустить 4 конструктора копирования?
При проверке показывает один, но это наверное из-за того что вы говорили, то есть компилятор оптимизирует, так что не могу проверить правильно ли я понял.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.02.2013, 02:44     Объясните неявное преобразование в этом случае
Еще ссылки по теме:

C++ неявное преобразование типов?
Продемонстровать неявное преобразование типов: из целого в вещественный и обратно C++
C++ Неявное преобразование типов

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

Или воспользуйтесь поиском по форуму:
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
17.02.2013, 02:44     Объясните неявное преобразование в этом случае #10
Цитата Сообщение от mzarb Посмотреть сообщение
должен будет запустить 4 конструктора копирования?
При проверке показывает один, но это наверное из-за того что вы говорили, то есть компилятор оптимизирует, так что не могу проверить правильно ли я понял.
почитайте какую-нибудь книгу по c++ (более менее не для чайников)
C++
1
A a = b;
это неявный вызов конструктора A::A(const B& b);
C++
1
2
A a;
a = b;
вызов operator=(const B& b), либо если такого нет, то воздание временного объекта a_ из b
A a_(b);
а потом вызов оператора присваивания
a = 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
28
29
30
31
32
#include <iostream>
#define DEBUG Debug(__FUNCTION__, __LINE__)
 
class Debug {
public:
    Debug (const char* f, int line) { std::cout << f << " (" << line << ")> "; }
    ~Debug () { std::cout << std::endl; }
    template <typename T> void operator << (const T& t) { std::cout << t; }
};
 
class B {
 
};
 
class C {
 
};
 
class A {
public:
  A (const B& b) { DEBUG; }
  A (const A& a) { DEBUG; }
  void operator= (const C& c) { DEBUG; }
};
 
int main () {
  DEBUG << "create b";        B b;
  DEBUG << "create c";        C c;
  DEBUG << "create a from b"; A a = b;
  DEBUG << "copy b to a";     a = b;
  DEBUG << "copy c to a";     a = c;
}
http://codepad.org/ygk2FJbY
Bash
1
2
3
4
5
6
7
8
9
main (28)> create b
main (29)> create c
main (30)> create a from b
A (22)> 
A (23)> 
main (31)> copy b to a
A (22)> 
main (32)> copy c to a
operator= (24)>
http://liveworkspace.org/code/3pwQyT$3
Bash
1
2
3
4
5
6
7
8
main (28)> create b
main (29)> create c
main (30)> create a from b
A (22)> 
main (31)> copy b to a
A (22)> 
main (32)> copy c to a
operator= (24)>
Поэтому explicit рулит

http://alenacpp.blogspot.com/2009/09/blog-post.html
Yandex
Объявления
17.02.2013, 02:44     Объясните неявное преобразование в этом случае
Ответ Создать тему
Опции темы

Текущее время: 08:44. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru