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

Время приобретения объектом константности - C++

Восстановить пароль Регистрация
 
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
20.07.2014, 17:31     Время приобретения объектом константности #1
Всем привет
Есть такая ситуация:
C++
1
2
3
4
5
6
7
8
// Функция:
void someFunc(const std::vector<MyObj> objects);
 
 
std::vector<MyObj> makeObjectsVector() { /* --- */ }
 
// Вызываю её так:
someFunc( makeObjectsVector() ); // сработает ли move-конструктор, ведь someFunc принимает const?
Добавлено через 4 минуты
Код собрался, даже не пищал, но если move-конструктор оставляет принятый как параметр объект in valid but unspecified state, то значит он должен как-то изменить состояние его, а сл-но константность параметра функции someFunc приобретается уже после перемещения?

К чему все это: в функции этот перемещаемый объект никак не изменяется, а только читается, а у меня привычка объявлять такие вещи как const.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.07.2014, 17:31     Время приобретения объектом константности
Посмотрите здесь:

C++ Работа с объектом.
C++ Проблема с объектом string
C++ Работа с классом и объектом Вектор
C++ Разница между объектом и экземпляром класса
C++ Задача на строки, с объектом класса string
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
-=ЮрА=-
Заблокирован
Автор FAQ
20.07.2014, 17:53     Время приобретения объектом константности #2
Цитата Сообщение от gromo Посмотреть сообщение
void someFunc(const std::vector<MyObj> &objects);
- !!!!
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
20.07.2014, 17:55  [ТС]     Время приобретения объектом константности #3
-=ЮрА=-, вы наверное имеете ввиду NamedReturnValueOptimization? Может это и сработает, но я хочу именно использовать перемещение, потому что оно гарантированно сэкономит ресурсы там, где NRVO может и не получиться.
-=ЮрА=-
Заблокирован
Автор FAQ
20.07.2014, 18:02     Время приобретения объектом константности #4
gromo, в твоём случае создаётся копия объекта
См ниже что вызовется при вызове SomeFunc1
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
33
34
#include <iostream>
using namespace std;
class CSomeClass
{
    public:
    CSomeClass();
    CSomeClass(const CSomeClass &pCopy);
    friend void SomeFunc1(const CSomeClass  obj);
    friend void SomeFunc2(const CSomeClass &obj);
};
 
CSomeClass::CSomeClass(){
    cout<<"DEFAULT CONSTRUCTOR"<<endl;
}
 
CSomeClass::CSomeClass(const CSomeClass &pCopy){
    cout<<"COPY CONSTRUCTOR"<<endl;
}
 
void SomeFunc1(const CSomeClass  obj){
    cout<<"SomeFunc1"<<endl;
}
 
void SomeFunc2(const CSomeClass &obj){
    cout<<"SomeFunc2"<<endl;
}
 
int main()
{
    CSomeClass pObj;
    SomeFunc1(pObj);
    SomeFunc2(pObj);
    return 0;
}
DEFAULT CONSTRUCTOR
COPY CONSTRUCTOR
SomeFunc1
SomeFunc2
http://codepad.org/sPPIfdry

Добавлено через 1 минуту

Не по теме:

Цитата Сообщение от gromo Посмотреть сообщение
но я хочу именно использовать перемещение,
- тогда сделай нормальный Swap

gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
20.07.2014, 18:36  [ТС]     Время приобретения объектом константности #5
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
См ниже что вызовется при вызове SomeFunc1
Так то да, вызовется копирующий конструктор. Однако в моем примере кода на вход someFunc подается объект из некого фабричного help-метода ( на практике это может быть std::make_pair, std::make_tuple...).
Если расширить ваш класс так
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
using namespace std;
class CSomeClass
{
    public:
    CSomeClass();
    CSomeClass(const CSomeClass &pCopy);
    friend void SomeFunc1(const CSomeClass  obj);
    friend void SomeFunc2(const CSomeClass &obj);
 
    CSomeClass(CSomeClass &&other) : m_variable(other.m_variable)
    {
        other.m_variable = 0;
        std::cout << "Move Constructor" << std::endl;
    }
    int m_variable;
};
 
CSomeClass::CSomeClass(){
    cout<<"DEFAULT CONSTRUCTOR"<<endl;
}
 
CSomeClass::CSomeClass(const CSomeClass &pCopy){
    cout<<"COPY CONSTRUCTOR"<<endl;
}
 
void SomeFunc1(const CSomeClass  obj){
    cout<<"SomeFunc1"<<endl;
}
 
void SomeFunc2(const CSomeClass &obj){
    cout<<"SomeFunc2"<<endl;
}
 
CSomeClass someClassFactory()
{
    CSomeClass csc;
    return csc;
//    return std::move(csc);
}
 
int main()
{
    CSomeClass pObj;
    SomeFunc1(pObj);
    SomeFunc2(pObj);
    std::cout << "-------------------------------------"   << std::endl;
 
    SomeFunc1( someClassFactory() );
 
    return 0;
}
При вызове SomeFunc1 не вызывается копирующего конструктора, сработала NRVO.
Но если в someClassFactory() раскомментировать 2 вариант return'a то сработает move-конструктор и опять же не будет копирования. Как видно, в move-конструкторе изменяется m_variable, даже если и параметр функции someFunc1 объявлен как const. А это и есть ответ на мой вопрос, т.е. объект приобретает константность после перемещения и move constructor все-таки сработает.

К сожаления codepad.org не распознает && поэтому могу только предоставить свой вывод в gcc.
Время приобретения объектом константности
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
20.07.2014, 18:59  [ТС]     Время приобретения объектом константности #6
___
-=ЮрА=-
Заблокирован
Автор FAQ
20.07.2014, 20:03     Время приобретения объектом константности #7
gromo, у тебя в коде глупость
Цитата Сообщение от gromo Посмотреть сообщение
CSomeClass(CSomeClass &&other)
http://codepad.org/3OM4ziqi

Добавлено через 1 минуту

Не по теме:

Ещё раз хочешь не убивая данных отдать их новому объекту - пиши Swap хочешь КК без создания временного объекта - пережавай константную ссылку.Не хочешь слушать дело твоё.

gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
20.07.2014, 20:09  [ТС]     Время приобретения объектом константности #8
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
у тебя в коде глупость
ну я ж написал, что этот онлайн-компилятор не кушает rvalue references, и выше прикрепил скриншот выдачи своего локального компилятора.

Добавлено через 3 минуты
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
пиши Swap хочешь КК без создания временного объекта - пережавай константную ссылку.
Зачем писать swap если он есть в STL? А с move конструктором обмен и так будет без временного объекта ( во всяком случае почти без затрат на его создание )
-=ЮрА=-
Заблокирован
Автор FAQ
20.07.2014, 20:16     Время приобретения объектом константности #9
gromo, присвоить нуль таким образом
other.m_variable = 0
контейнеру у тебя не выйдет. Работай с указателями и swap-ом, так сможешь обменять данные без перевыделений. Либо приведи нормальный код чтобы можно было толком понять что куда хочешь переместить.
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
20.07.2014, 20:21  [ТС]     Время приобретения объектом константности #10
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
присвоить нуль таким образом
other.m_variable = 0
контейнеру у тебя не выйдет.
это ясно, здесь переменная типа int для примерa. Контейнеры работают с аллокаторами, которые и распоряжаются перемещаемыми ресурсами. ( в зависимости от propagate_on_container_move_assignment ) На самом деле там может ничего и не присваиваться, только при попытке доступа к перемещенному контейнеру ( или любому другому объекту ) получим UB.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
20.07.2014, 20:50     Время приобретения объектом константности #11
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
у тебя в коде глупость
Ох, снова ты не разобрался что к чему и начинаешь писать чушь.
Твой любимый codepad не поддерживает C++11. И ты, судя по всему, тоже не знаешь, что такое && в современном C++.

Добавлено через 13 минут
gromo, вот, можно посмотреть на цепочку вызовов:
http://coliru.stacked-crooked.com/a/e3e0fd28be3909cb
Основной момент в использовании ключа -fno-elide-constructors иначе срабатывает оптимизация и дело до конструктора перемещения не доходит вовсе.
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
20.07.2014, 21:12  [ТС]     Время приобретения объектом константности #12
Цитата Сообщение от Tulosba Посмотреть сообщение
иначе срабатывает оптимизация и дело до конструктора перемещения не доходит вовсе.
Ого, лучше наверное пускай срабатывает оптимизация - 2 вызова против 6 (!!!).
Только один момент остался неясен.
Если с -fno-elide-constructors то имеем такую цепочку ( метки #1 #2 )
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
#include <vector>
#include <iostream>
 
struct V
{
    V() { std::cout << "ctor\n"; }
    ~V() { std::cout << "dtor\n"; }
    V(const V&) { std::cout << "copy ctor\n"; }
    V(V&&) { std::cout << "move ctor\n"; }
};
 
// Функция:
void someFunc(const V v) // #2 перемещение, деструктор, деструктор.
{
    std::cout << "someFunc" << std::endl;
}
 
V makeObject()
{
    return V(); // #1  конструктор, перемещение, деструктор
}
 
int main()
{
    someFunc( makeObject() );
}
Для чего второй раз вызвался деструктор в #2 ?
-=ЮрА=-
Заблокирован
Автор FAQ
20.07.2014, 21:24     Время приобретения объектом константности #13
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <vector>
#include <iostream>
using namespace std;
 
class CSomeClass
{
    protected:
    vector<int> * lpData;
    public:
    CSomeClass();
    void SwapData(CSomeClass &pCopy);
    void SetItemCount(int count= 0);
    size_t GetItemCount() const;
};
 
CSomeClass::CSomeClass(){
    lpData = 0;
}
 
void CSomeClass::SwapData(CSomeClass &pCopy){
    swap(lpData, pCopy.lpData);
}
 
void CSomeClass::SetItemCount(int count)
{
    if( lpData )
        lpData->resize(count);
    else
    if( lpData = new vector<int>() )
        SetItemCount(count);
}
 
size_t CSomeClass::GetItemCount() const{
    size_t count = 0;
    if( lpData )
        count = lpData->size();
    return count;
}
 
void Notify(const CSomeClass &srs, 
const  CSomeClass &dst, const  CSomeClass &cpy, const char * msg = 0);
 
int main()
{
    CSomeClass srs;
    CSomeClass dst;
    CSomeClass cpy;
    Notify(srs, dst, cpy, "INIT : ");
    srs.SetItemCount(10);
    Notify(srs, dst, cpy, "SRS::SetItemCount(10) : ");
    dst.SwapData(srs);
    Notify(srs, dst, cpy, "DST::SwapData(SRS) : ");
    cpy.SetItemCount(5);
    Notify(srs, dst, cpy, "CPY::SetItemCount(10) : ");
    cpy.SwapData(dst);
    Notify(srs, dst, cpy, "CPY::SwapData(DST) : ");
    cin.get();
    return 0;
}
 
void Notify(const CSomeClass &srs, const CSomeClass &dst,const  CSomeClass &cpy, const char * msg)
{
    if( msg )
    cout<<msg<<endl;
    cout<<"SRS : "<<srs.GetItemCount()<<endl;
    cout<<"DST : "<<dst.GetItemCount()<<endl;
    cout<<"CPY : "<<cpy.GetItemCount()<<endl;
}
INIT :
SRS : 0
DST : 0
CPY : 0
SRS::SetItemCount(10) :
SRS : 10
DST : 0
CPY : 0
DST::SwapData(SRS) :
SRS : 0
DST : 10
CPY : 0
CPY::SetItemCount(10) :
SRS : 0
DST : 10
CPY : 5
CPY::SwapData(DST) :
SRS : 0
DST : 5
CPY : 10
http://ideone.com/cPRRfj
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
20.07.2014, 21:43     Время приобретения объектом константности #14
gromo, три конструктора, три деструктора. Всё вроде бы логично.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.07.2014, 22:14     Время приобретения объектом константности
Еще ссылки по теме:

Обход константности переменной C++
Возвращение объектом значения C++
Возврат значения объектом класса C++

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

Или воспользуйтесь поиском по форуму:
gray_fox
20.07.2014, 22:14     Время приобретения объектом константности
  #15

Не по теме:

Цитата Сообщение от gromo Посмотреть сообщение
этот онлайн-компилятор не кушает rvalue references
ideone может, если что.

Yandex
Объявления
20.07.2014, 22:14     Время приобретения объектом константности
Ответ Создать тему
Опции темы

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