2017-03-28 5 views
1
#include <iostream> 
#include <utility> 
int main() 
{ 
    double* ptr; 
    { 
     double temp = 5.5; 
     ptr = new double(std::move(temp)); 
    } // temp dies here 
    std::cout << *ptr << "\n"; 
    delete ptr; 
} 

나는이 작품을 알고있다. 하지만이 "5.5"값이 동일하지만 동적 할당 주소로 직접 이전 될지 여부가 중요합니다. 즉, temp이 더 이상 유효하지 않을 때에도 ptr은 여전히 ​​temp을 가리 킵니까?변수 수명 연장하기

우리가 단기 지역 범위에서 장기 저장으로 이동하고 나중에 변수가 언제 죽을지를 결정하는 거대한 배열이라고 가정 해 봅시다.

더 설명 : 우리는 주소의 메모리에 위치하고 있다고 가정

. 그것은 잠시 후에 죽을 것입니다. 그러나 죽기 전에 우리는 멋진 속임수를 만들고이 같은 A 주소를 잠그면 죽지 않을 것입니다. 따라서 우리는 그것을 유지하기 위해 물건을 복사 할 필요가 없었습니다. 우린 그냥 잠 갔어. C++에서 가능합니까?

+1

아니요, 주소가 스택에 있으면 함수를 반환 한 후 주소를 사용할 수 없습니다. –

+0

_ 살아 남기 위해 물건을 복사 할 필요가 없었습니다 ._ static 변수의 로컬 변수 나 static 변수와 비슷합니까? – txtechhelp

+1

''double'에'std :: move'는 아무 것도하지 않고, 마침내 단지 복사본을 만듭니다. – Jarod42

답변

2

C++에서는 직접 지원하지 않습니다. 오브젝트가 유효 범위를 벗어나면 수명이 끝나고 해당 오브젝트에 남아있는 포인터는 유효하지 않습니다 (즉, 참조 해제하면 정의되지 않은 동작이 호출 됨).

그러나,이 코드에서 어떤 일이 일어나는지 정말되지 않습니다 : 여기에 std::move

double* ptr; 
{ 
    double temp = 5.5; 
    ptr = new double(std::move(temp)); 
} // temp dies here 

는 무 조작 (아무것도하지 않는다), 그리고 코드는 더 간단 변형

double* ptr; 
{ 
    double temp = 5.5; 
    ptr = new double(temp); 
} // temp dies here 
에 해당

double 개체가 동적으로 할당되고 5.5으로 초기화됩니다. 여기에는 특별한 것이 없습니다.

그러나 하나의 double 개체 대신 거대한 배열이 있다면 어떻게 될까요? 그런 다음 std::vector 또는 std:valarray을 사용하고 있으며 해당 데이터 요소는 항상 동적으로 할당됩니다. 할 수 없습니다 (당신이 std::array를 사용하거나 내장 된 배열 유형, 당신은 당신의 가치를 복사해야하는 경우, 또는

std::vector<double> values; 
{ 
    std::vector<double> temp; 
    // fill the temp array 
    if (... want to extend life time of temp ...) 
    { 
     values = std::move(temp); 
    } 
} // temp dies here 
// now 'values' is either empty or holds the temp values 

: 그럼, 그것은 감각의 예에서와 같이 std::move를 사용 할 수 있습니다, 그것은 딱 맞는 동작을 가지고 움직임).

0

C++ reference - std::move에서 표준 : 이동 물체 t 다른 개체 t에서 자원의 효율적인 전달을 가능하게, 즉 "에서 이동"될 수 있다는 것을 나타 내기 위해 사용된다.

특히 std :: move는 인수 t를 식별하는 xvalue 표현식을 생성합니다. rvalue 참조 유형에 대한 static_cast와 정확히 같습니다.

그래서 xvalue, rvalue ...은 무엇입니까? 모든 CPL 표현식은 "오른쪽 모드"로 평가 될 수 있지만, 표현의 특정 종류의 왼쪽 "에서 의미가있다 :

C++ reference - value_category

에서 프로그래밍 언어 CPL은 표현식 값 범주를 소개 처음 - 핸드 모드 ".오른쪽 모드에서 평가할 때 표현식은 값 (오른쪽 값 또는 rvalue) 계산의 규칙으로 간주됩니다. 왼손 모드에서 평가할 때 표현식은 주소 (왼쪽 값 또는 왼쪽 값)를 효과적으로 제공합니다. 여기에서 "왼쪽"과 "오른쪽"은 "과제의 왼쪽"과 "배정 된 권리"를 의미했습니다.

C++ C++ 11 이동 의미론의 도입

11 값 카테고리는 표정 개의 독립적 인 성질을 특성화하기 위해 재정의 하였다 [5] :

신원 있습니다 표현식이 다른 표현식과 동일한 엔티티를 참조하는지 여부를 판별 할 수 있습니다 (예 : 직접 또는 간접적으로 획득 한 오브젝트 또는 식별 된 기능의 주소를 비교하여).

에서 이동할 수 있습니다. 이동 생성자, 이동 할당 연산자 또는 이동 의미를 구현하는 다른 함수 오버로드가 표현식에 바인딩 될 수 있습니다. C++ 11에서

, 표현하는 것이 :

  • 이 ID를 가지며 식 좌변이라고에서 이동할 수 없습니다;
  • 은 신원을 가지고 있으며 xvalue 표현식이라고 불리는 곳에서 이동할 수 있습니다.
  • 은 신원이 없으므로 prvalue ("pure rvalue") 표현이라고합니다.
  • 은 ID가없고 이동할 수 없습니다 [6].

ID가있는 표현식을 "glvalue expressions"(glvalue는 "일반화 된 lvalue"를 나타냄)라고합니다. lvalues와 xvalues는 모두 glvalue 표현입니다.

이동할 수있는 표현식을 "rvalue expressions"이라고합니다. prvalues와 xvalues는 모두 rvalue 표현식입니다.

  • temp (double)에는 "ID"가 있습니다.
  • (더블) "로 이동 될 수 없다"임시
    은 "생성자 이동 할당 연산자 또는 의미론 이동 구현하는 다른 함수의 과부하 이동"그래서 단지 값이 사용될

이 없어 새로운 변수를 생성한다.