2012-05-05 3 views
0
class A 
{ 
public: 
    A() 
    { 
     cout << "A()" << endl; 
    } 

    A(const A&) 
    { 
     cout << "A(const A&)" << endl; 
    } 

    A(A&&) 
    { 
     cout << "A(A&&)" << endl; 
    } 

    A& operator=(const A&) 
    { 
     cout << "A(const A&)" << endl; 
    } 

    A& operator=(A&&) 
    { 
     cout << "A(const A&&)" << endl; 
    } 

    ~A() 
    { 
     cout << "~A()" << endl; 
    } 
}; 

A&& f_1() 
{ 
    A a; 
    return static_cast<A&&>(a); 
} 

A f_2() 
{ 
    A a; 
    return static_cast<A&&>(a); 
} 

int main() 
{ 
    cout << "f_1:" << endl; 
    f_1(); 
    cout << "f_2:" << endl; 
    f_2(); 
} 

выход:Это хорошая практика, объявляющая функцию BigStruct && foo (...);

f_1: 
A() 
~A() 
f_2: 
A() 
A(A&&) 
~A() 
~A() 

В примере кода, очевидно, указывает на то, что f_1() является более эффективным, чем F_2().

Итак, мой вопрос:

Если мы всегда объявляем функцию как some_return_type & & F (...); вместо some_return_type f (...); ?

Если ответ на мой вопрос, правда, тогда другой вопрос следующим образом:

Там было много много функций, объявленных в some_return_type е (...); в мире С ++, мы должны изменить их на современную форму?

+2

Вы скомпилировали его с помощью '-Wall'? msgstr "предупреждение: ссылка на локальную переменную 'a' возвращается. Это в определении 'f_1' ... – mfontanini

+0

http://stackoverflow.com/questions/4986673/c11-rvalues-and-move-semantics-confusion – Fanael

ответ

6

это хорошая практика, объявляя функцию как BigStruct & & Foo (...);

Ужасная практика. Как и в случае с lvalue-reference, что вы делаете, возвращает ссылку местному объекту. К моменту, когда вызывающий абонент получает ссылку, упомянутый объект уже ушел.

Было много функций, объявленных как some_return_type f (...); в мире С ++, мы должны изменить их на современную форму?

Современная форма - это форма, в которой они уже были построены (с учетом только типов возврата). Стандарт был изменен, чтобы сделать общую форму более эффективной, чтобы не переписывать всех своих кодов.

Сейчас существуют не современные версии там, как void f(type& t) вместо type f() когда fсоздает объект. Те, кого мы хотим изменить в современной форме type f() как обеспечивает более простой интерфейс, рассуждать о том и обеспечивать простой пользовательский код:

Пользователи не должны думать ли объект модифицирована или создано:

void read_input(std::vector<int>&); 

Это добавление или замена вектора?

И сделать код звонящего проще:

auto read_input(); 

против

std::vector<int> v; 
read_input(v); 
0

В f_2 вы предотвратить компилятор от применения NRVO. Когда вы бросаете бросок и скомпилируете с включенными оптимизациями, вы обнаружите, что это так же эффективно. Абсолютно никакой необходимости в литье к ссылке, это не имеет смысла в f_2.

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