2017-05-11 41 views
9

Czy można bezpiecznie przekazywać parametry funkcji, takie jak getAName(getA().get())? getA() zwraca obiekt unique_ptr<A>.C++: Czy można bezpiecznie przekazywać argumenty takie jak unique_ptr :: get() do funkcji

Testuję z całym kodem poniżej na VS 2010, to działa. Ale chciałbym się upewnić, czy jest to standard C++, czy jest bezpieczny z innymi kompilatorami C++?

#include "stdafx.h" 
#include <memory> 
#include <iostream> 

using namespace std; 

class A 
{ 
public: 
    A(){ cout<<"A()"<<endl;} 
    ~A(){ cout<<"~A()"<<endl;} 

    string name() { return "A"; } 
}; 

std::unique_ptr<A> getA() 
{ 
    return std::unique_ptr<A>(new A());; 
} 

void getAName(A* a) 
{ 
    if(a) 
    { 
     cout << a->name().c_str() << endl; 
    } 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    getAName(getA().get()); 
    return 0; 
} 

Wyjścia w konsoli to:

A() 
A 
~() 

Jest to konieczne, aby kod jak poniżej bezpieczny dla wszystkich kompilatorów?

unique_ptr<A> a = getA(); 
getAName(a.get()); 
+1

c_str() nie jest wymagane, jeśli używasz cout – Kapil

Odpowiedz

7

Jest bezpieczny. getA() zwraca wartość temporarystd::unique_ptr, która zostanie zniszczona po pełnym wyrażeniu, co stanowi wywołanie getAName(). Tak więc wewnątrz ciała getAName() wskazany kurs pozostaje ważny.

wszystkie tymczasowe obiekty są niszczone jako ostatni krok w ocenie pełnym wyrażenie (leksykalnie) zawiera punkt, w którym zostały one utworzone, ...

Zauważ, że jeśli wskaźnik jest przekazywana w przechowywane gdzieś (np. zmienna globalna), a następnie używane później (tj. po wywołaniu getAName()), obiekt wskazany przez wskaźnik został zniszczony przez tymczasowy obiekt i wskaźnik się zwisał; wtedy szacunek na to byłby UB. W takim przypadku, jak pokazałeś, możesz potrzebować zmiennej nazwanej.

+0

Btw co oznacza UB? – Kapil

+0

@Kapil [Niezdefiniowane zachowanie] (https://en.wikipedia.org/wiki/Undefined_behavior). – songyuanyao

+0

Czy nie będzie to błąd segmentacji (SIGSEV)? – Kapil