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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
#1

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

15.02.2013, 13:04. Просмотров 562. Ответов 9
Метки нет (Все метки)

C++
1
scoped_ptr p = new Object();
То есть "p" неявно преобразовывается в указатель, но как не понятно. Это я встретил просматривая вот это. В коментариях был ответ "scoped_ptr p = new Object();
Здесь работает неявное преобразование. У scoped_ptr в конструкторе указан аргументом Object*, справа от знака "=" как раз такой указатель и создаётся.
Компилятор в таком случае преобразует эту конструкцию к scoped_ptr p(new Object());
т.е. такой вызов эквивалентен вызову конструктора. За подробностями надо гуглить по ключевому слову explicit".
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.02.2013, 13:04
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Объясните неявное преобразование в этом случае (C++):

Неявное преобразование типов - C++
если я правильно понял, то explicit работает таким образом: class abc { int x; public: abc(int x_):x(x_){} ~abc(){} };

Неявное преобразование переменных - C++
Добрый вечер! Хочу попросить помощи в разъяснении следующей ситуации: есть код: #include <iostream> using namespace std; ...

Неявное преобразование типов? - C++
есть класс Vector затем с его помощью создается класс Matrix (матрица - массив векторов) дошла очередь до операции умножения матрицы...

Неявное преобразование типа - C++
Привет. Решаю задачу, не могу решить проблему. Есть класс 'time' и производный от него класс 'interval'. 1 - содержит поля h, m, s,...

Неявное преобразование типов - C++
Здравствуйте, определен класс: template<typename T> class Polynomial { public: explicit...

Неявное преобразование типа данных через структуры - C++
Помню что вроде был в С/С++ такой прием, который позволял посмотреть на содержимое переменной одного типа с точки зрения другого типа....

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
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
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
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
2788 / 1602 / 145
Регистрация: 03.12.2007
Сообщений: 4,193
Завершенные тесты: 1
15.02.2013, 18:28 #5
В видео по той ссылке там свой scoped_ptr, а не из Boost, и там нет ни шаблонов, ни explicit.
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 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
Каратель
Эксперт С++
6553 / 3973 / 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 конструктора копирования?
При проверке показывает один, но это наверное из-за того что вы говорили, то есть компилятор оптимизирует, так что не могу проверить правильно ли я понял.
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.02.2013, 02:44
Привет! Вот еще темы с ответами:

Неявное восходящее преобразование при защищенном/закрытом наследовании - C++
Здравствуйте. Читаю книгу Стивена Прата по C++. Попался непонятный момент: в одной таблице (в таблице 14.1 в 6-й рус. редакции на стр....

Продемонстровать неявное преобразование типов: из целого в вещественный и обратно - C++
Помогите решить задачи по С++, никак не могу, вся надежда только на вас. 1. Даны вещественные и целые числа. Наглядно продемонстрируйте...

Как запретить компилятору неявное преобразование из числового типа в символьный? - C++
У мя возникла такая проблема: я ввожу данные типа char и мне надо быть уверенным, что я ввел именно символ, т.е. если я ввожу число мне...

Есть ли утечка памяти в этом случае? - C++
_Доброго денёчка всем. Прохожу тему на указатели и ссылки. Делаю упражнение на тему &quot;написать программу, вызывающую утечку памяти&quot;. Смысл...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
17.02.2013, 02:44
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru