2015-06-15 3 views
0

у меня есть этот пример кода:станд :: перейти к функции

#include <iostream> 

class Struct { 
public: 
    Struct() { std::cout << "0" << std::endl; } 
    Struct(Struct&) { std::cout <<"1"<<std::endl;} 
    Struct(const Struct&) { std::cout << "2" << std::endl; } 
}; 

class Struct2 { 
public: 
    Struct s; 

    Struct2() {} 
    void setMember(const Struct& aux) { s = aux; } 
}; 

int main() 
{ 
    Struct s; 
    Struct2 s2; 
    s2.setMember(s); 
} 
// http://coliru.stacked-crooked.com/a/dd57e8af23f6db4b 

Doubt 1:

Он Printting два 0, так как конструктор в основной и конструкции элемента of Struct2.

Дело в том, что я ожидал трех 0, потому что «setMember» получает копию 's', правильно? Что происходит?

Сомнение 2:

Я думал в это положить:

s2.setMember(std::move(s)); 

Как я не буду использовать 'S' снова, но setMember не имеет '& &' указано, Это нормально? Нужно ли мне это делать? :

s = std::move(aux); 

Или с одним из основных достаточно?

Сомнение 3:

std::vector<A> vectorA; 

int main() 
{ 
    A a; 
    // modifies a ... 
    vectorA.push_back(std::move(a)); 
} 

Является ли это правильно? Я оптимизирую что-нибудь движущееся? Он не будет использоваться больше, и я хочу, чтобы держать его в векторе

Благодарности

+0

Передача аргументов в качестве ссылки - это полная противоположность от передачи как значения (копия). здесь, не ваш c.tros передает аргумент по значению. –

+0

Если вы не понимаете механизм передачи по ссылке, возможно, вам стоит прочитать немного больше о базовом C++ перед погружением в семантику перемещения. – undu

ответ

2

, потому что «setMember» получает копию «с», не так ли?

Ну, нет. Он получает const& и копирует оператор присваивания. Поскольку вы не перегружали оператор присваивания, ничего не распечатывается.


s2.setMember(std::move(s));

Это ничего не решит; std::move будет просто отличать s в rvalue, но внутри функции все равно const&.


правило: пройти по значению, съехать внутри:

void setMember(Struct aux) { s = std::move(aux); } 

Таким образом, это будет "автомагически" работа; копирование lvalues ​​на интерфейсе/перемещение rvalues ​​в значение параметра, а затем перемещение значения параметра в фактический элемент объекта.

Конечно, чтобы обеспечить оптимальное использование этого механизма, вам нужно RValue прошел там, так что ...

Struct s; 
Struct2 s2; 
s2.setMember(std::move(s)); 

Или, может быть ...

s2.setMember(Struct()); 

Это, как говорится, ваш старый код не сломается.


Что касается третьего примера, да, это нормально, я бы Altough вероятно либо

  • шага, чтобы изменения a другой функции и push_back(function())
  • шага, чтобы изменения a до A s изготовитель и его эксплуатация emplace_back
+0

Итак, в конце, который является наиболее эффективным способом? Я просто хочу назначить это 'члену s2. s2.setMember (std :: move (s)), то? – user3468999

+0

@ user3468999 Разрабатывайте «эффективный». Если вы хотите избежать копирования, не пишите заявления, которые вызывают копии, я думаю, что это довольно просто. Ключевым моментом для понимания является то, что принятие значения не обязательно копирует. Так что я предложил (принимая значение) будет хорошо. –

+0

Также я обновил сообщение третьим сомнением, если бы вы могли проверить его, пожалуйста ... :) – user3468999

Смежные вопросы