Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 5.00
kravam
быдлокодер
1703 / 890 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
#1

Конструктор, принимающий в качестве аргумента ссылку на объект, всё портит - C++

08.09.2013, 14:08. Просмотров 1957. Ответов 47
Метки нет (Все метки)

Друзья! Вот корректный код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class foo
{
public:
                foo()
                    { 
                    }
                foo(int x)
                    { 
                    }
                ~foo(){}
};
 
 
//+++++++++++++++++++++++++++++++++++++
 
int main()
{
    foo c2 = foo (9);
}
А вот некорректный:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class foo
{
public:
                foo()
                    { 
                    }
                foo(int x)
                    { 
                    }
                foo(foo& f)
                    { 
                    }
                ~foo(){}
};
 
 
//+++++++++++++++++++++++++++++++++++++
 
int main()
{
    foo c2 = foo (9);
}
Ошибки,

Bash
1
2
3
4
5
6
7
8
9
10
main_p.cpp: In function 'int main()':
main_p.cpp:21:20: error: no matching function for call to 'foo::foo(foo)'
main_p.cpp:21:20: note: candidates are:
main_p.cpp:10:17: note: foo::foo(foo&)
main_p.cpp:10:17: note:   no known conversion for argument 1 from 'foo' to 'foo&'
main_p.cpp:7:17: note: foo::foo(int)
main_p.cpp:7:17: note:   no known conversion for argument 1 from 'foo' to 'int'
main_p.cpp:4:17: note: foo::foo()
main_p.cpp:4:17: note:   candidate expects 0 arguments, 1 provided
Выполнение завершено
первая же из которых вводит в ступор. У меня нет вызова foo::foo(foo)! Если бы он был, то первый код не скомпилился бы. В общем, непонятно, почему foo(foo& f) всё портит во втором коде, хотелось бы разъяснений, тык скыть. Спасибо, кто откликнется.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.09.2013, 14:08
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Конструктор, принимающий в качестве аргумента ссылку на объект, всё портит (C++):

Компилятор требует конструктор, принимающий аргументом экземпляр того же класса (не ссылку) - C++
Доброго времени суток. Проблема такова: имеется ряд нижеприведённых классов (для простоты всё, что навскидку не касается данной...

Научить метод принимать в качестве аргумента объект своего класса и дочерних классов - C++
Как научить метод принимать в качестве аргумента объект своего класса и дочерних классов? Как их передавать при вызове метода?

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

Конструктор, принимающий параметр - C++
привет. посмотрите листинг: // Префиксный и постфиксный операторы инкремента #include <iostream> using namespace std; class...

Создать функцию, имеющую два аргумента и возвращающую в качестве аргумента число из отрезка [a,b] - C++
Создать функцию, которая будет иметь два целочисленных параметра a и b, и в качестве своего значения возвращать случайное целое число из...

Конструктор принимающий два целочисленных значения - C++
Добрый день существует Конструктор принимающий два целочисленных значения, как можно просмотреть его значение в теле int main() ? A(int...

47
kravam
быдлокодер
1703 / 890 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
09.09.2013, 20:53  [ТС] #16
А какой бы конструктор копирования подошёл для такого кода?
C++
1
foo c2 = foo (9);
Минимальный компилящийся код, пожалуйста. Без наворотов.
0
BumerangSP
4287 / 1409 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
09.09.2013, 20:56 #17
C++
1
2
3
4
5
6
7
8
9
10
11
class foo
{
public:
    foo(int x) {}
    foo(const foo& f) {}
};
 
int main()
{
    foo c2 = foo (9);
}
или даже так:
C++
1
2
3
4
5
6
7
8
9
10
class foo
{
public:
    foo(int x) {}
};
 
int main()
{
    foo c2 = foo (9);
}
0
DiffEreD
1431 / 768 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.09.2013, 20:57 #18
Вот мое понимание всего этого:
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
class foo
{
public:
   foo() {}
   foo(int x) {}
   foo(foo& f) {}
   ~foo(){}
};
 
int main()
{
   //int& reference = 9;        //Error
   const int& creference = 9; //Ok
 
   //foo& foo_ref = foo(9);       //Error
   const foo& foo_cref = foo(9);//Ok
 
   //foo f = foo(9); //Error: foo(9) есть rvalue; конструктору копий передается
                     //rvalue, а он принимает неконстантную ссылку что не допускается
 
   foo f(9);
   foo& no_const_ref = f; //Ok
   foo f2 = f; //Ok, конструктору копий передается lvalue
   foo f3 = no_const_ref; //Ok
   foo f4 = foo_cref;     //Error
 
   return 0;
}
0
kravam
быдлокодер
1703 / 890 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
09.09.2013, 21:03  [ТС] #19
Что и требовалось доказать. Надеюсь я ничьих чувств не задену, если вставлю сюда отладочную надпись, которую НИКТО НИКОГДА НЕ УВИДИТ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
class foo
{
public:
    foo(int x) {}
    foo(const foo& f) {printf ("вот её никто никогда не увидит\n");}
};
 
int main()
{
    foo c2 = foo (9);
    getchar ();
}
Так почему же когда я пишу КК, который почему-то использовать нельзя (хотя он синтаксический правильный)- компилятор ругается. Но когда ему подсовываешь тот КК, который можно использовать (почему-то) компилятор его не использует? Фигня какая-то
0
Voivoid
675 / 278 / 12
Регистрация: 31.03.2013
Сообщений: 1,339
09.09.2013, 21:39 #20
В данном случае компилятор в целях оптимизации избавляется от лишнего вызова конструктора копирования
0
Jupiter
Каратель
Эксперт С++
6561 / 3982 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
09.09.2013, 21:46 #21
Цитата Сообщение от kravam Посмотреть сообщение
Фигня какая-то
copy elision
Цитата Сообщение от kravam Посмотреть сообщение
которую НИКТО НИКОГДА НЕ УВИДИТ?
-fno-elide-constructors для gcc
0
Hrobak
289 / 169 / 11
Регистрация: 22.03.2010
Сообщений: 483
Завершенные тесты: 1
09.09.2013, 21:47 #22
Цитата Сообщение от kravam Посмотреть сообщение
которую НИКТО НИКОГДА НЕ УВИДИТ
А ведь с опцией -fno-elide-constructors увидят. Ведь без учета оптимизаций здесь и должна быть ошибка компиляции: вы не передаете конструктору копирования lvalue
0
grizlik78
Эксперт С++
1970 / 1463 / 122
Регистрация: 29.05.2011
Сообщений: 3,029
09.09.2013, 21:50 #23
Просто конструкторы копирования у kravam "любимая мозоль"
0
DiffEreD
1431 / 768 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.09.2013, 21:53 #24
RVO и NRVO
0
kravam
быдлокодер
1703 / 890 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
09.09.2013, 22:02  [ТС] #25
Цитата Сообщение от Voivoid Посмотреть сообщение
В данном случае компилятор в целях оптимизации избавляется от лишнего вызова конструктора копирования
Очень может быть. В таком случае зачем он требует КК (назовём его "правильный"), если при предоставлении ему правильного КК он от него избавляется в целях оптимизации? Типа- дай-ка, kvaram, я посмотрю, а умеешь ли ты писать правильные КК?

Добавлено через 3 минуты
Цитата Сообщение от grizlik78 Посмотреть сообщение
Просто конструкторы копирования у kravam "любимая мозоль"
ого! Но так-то ситуации немного разнятся. В той теме я разобрался, почему КК не вызывается- просто объект уже создаётся по месту, что называется. Так он и в этой теме тоже воздаётся по месту. Но компилятор зачем-то требует ПРАВИЛЬНЫЙ КК, а потом него не использует (коль скоро оптимизирует код- создаёт объект там, где он будет в конце концов). Предметы у тем всё-таки разные.
0
ValeryS
Модератор
6729 / 5138 / 484
Регистрация: 14.02.2011
Сообщений: 17,232
09.09.2013, 22:04 #26
Цитата Сообщение от kravam Посмотреть сообщение
В таком случае зачем он требует КК (назовём его "правильный"), если при предоставлении ему правильного КК он от него избавится в целях оптимизации?
потому что сначала идет компиляция а потом оптимизация( уже бинарного кода)
у тебя ошибка на этапе компиляции, до оптимизатора дело не доходит
оптимизировать нечего, код не создан
0
grizlik78
Эксперт С++
1970 / 1463 / 122
Регистрация: 29.05.2011
Сообщений: 3,029
09.09.2013, 22:04 #27
Цитата Сообщение от kravam Посмотреть сообщение
Очень может быть. В таком случае зачем он требует КК (назовём его "правильный"), если при предоставлении ему правильного КК он от него избавится в целях оптимизации?
Потому, что это разные этапы. На этапе синтаксического разбора компилятор "не задумывается" об оптимизации. А на этапе оптимизации уже поздно делать послабления. Да и не нужно.
0
kravam
быдлокодер
1703 / 890 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
09.09.2013, 22:06  [ТС] #28
Цитата Сообщение от Hrobak Посмотреть сообщение
А ведь с опцией -fno-elide-constructors увидят. Ведь без учета оптимизаций здесь и должна быть ошибка компиляции: вы не передаете конструктору копирования lvalue
Специально для хороших парней не поленюсь повторить- меня не интересует, как ОБЯЗАТЕЛЬНО вызвать КК. Меня интересует, почему компилятор требует правильный КК, а потом его в целях оптимизации или чего там убирает на фиг.
0
Hrobak
289 / 169 / 11
Регистрация: 22.03.2010
Сообщений: 483
Завершенные тесты: 1
09.09.2013, 22:26 #29
Оптимизация может происходить на разных стадиях компиляции, но, как правило, как выше написал grizlik78, оптимизации происходят после синтаксического и семантического анализа кода.
0
kravam
быдлокодер
1703 / 890 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
10.09.2013, 21:56  [ТС] #30
Многие вопросы я уже выяснил. Но один, очень важный не выяснил, а именно: каков код, в котором использовался бы конструктор который не const?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
class foo
{
public:
    foo(int x) {}
    foo(const foo& f) {printf ("KK\n");
}
};
 
int main()
{
    foo c2 = foo (9);
    getchar ();
}
компилим с опцией
Bash
1
-fno-elide-constructors
, дабы компилятор не вздумал не создавать временные объекты. Так, а теперь хотелось бы увидеть аналогичный работоспособный код с конструктором, который
C++
1
foo(foo& f)
(он же верен!) То есть чтобы также, была одна из ситуаций, при которой вызывается КК, (а их напомню, 3, описанных в книге:

1) Когда возвращаемое значение функции имеет тип класса
2) Когда аргумент имеет тип класса
3) Когда один объект используется для инициализаци другого объекта)


Ну и чтобы вызвался
C++
1
foo(foo& f)
. Всё. Вся просьба.
0
10.09.2013, 21:56
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.09.2013, 21:56
Привет! Вот еще темы с ответами:

сегодня наконец то понял что такое КЛАСС, и ОБЪЕКТ. понято всё, кроме одного - зачем всё это? в смысле, можно же без этого? так зачем жизнь усложнять? - C++
сегодня наконец то понял что такое КЛАСС, и ОБЪЕКТ. понято всё, кроме одного - зачем всё это? в смысле, можно же без этого? так зачем жизнь...

Функция в качестве аргумента - C++
Мне нужно написать программу, которая будет включать в себя список, который можно добавлять, проверять его заполнение, а также обрабатывать...

Передача шаблона в качестве аргумента - C++
Всем доброго дня. Есть шаблон: template &lt;typename T, ushort cnt&gt; struct Array { private: ushort size; public: T...

Шаблон в качестве аргумента метода(функции) - C++
Доброго дня! Возник вопрос. Существует ли возможность определить параметр метода, указав тип шаблона, но не указывая конкретные типы...


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

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