inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

173만명의 커뮤니티!! 함께 토론해봐요.

r-value reference와 std::move

미해결

홍정모의 따라하며 배우는 C++

안녕하세요! 항상 수고 많으십니다. r-value 레퍼런스와 move 함수에 대해 궁금한 것이 몇 있는데 나름 찾아봤지만 해소되지않은 부분이 있어 이렇게 여쭤봅니다. 아래와 같이 && 를 통해 r-value 를 받고있는데요, { int && ref = 5; cout << ref << endl; //ok ref = 3; // ok cout << &ref << endl; //ok } { ref; //error, 정의된 scope 밖 } 원래 r-value 이던 5 는 잠시 레지스터든 어디에 임시 생성됐다가 표현식( ; )이 끝나면 바로 사라질 예정이었지만 l-value 로 바뀌어 메모리에 직접 저장되는 형식으로 되어, l-value 처럼 작동한다는 것이 적절한 이해인가요? (scope안에서는 계속 데이터 유효, scope 밖은 자동소멸 등..) move 함수에 대해서, move 는 인자로 들어간 것을 r-value 로 리턴하여 소유권을 이전, 및 자신의 소유권은 박탈해줍니다. 다음의 예시에서, string&& s 가 r-value 인 abc 를 받고있는데요, 이때 b 는 move(s) 를 통해 abc 에 대한 소유권을 이전받고, s 는 소유권을 박탈당해서 코드 실행시 다음의 결과가 나옵니다. b 는 abc를 정상출력, s 는 소유권을 박탈당해 아무것도 출력안함. 즉 move 가 소유권 이전, 박탈을 잘 해주는데요, 한편, (15.4강 2:54부근) 에서 가운데를 보면 res1 이 move 를 통해 r-value 로 리턴되고 res2 로 소유권(포인팅 주소) 이전 및 자신은 박탈 되는 것 처럼 보입니다. 명확히 확인해보기 위해 저 주황줄 코드가 호출하는 생성자에 아래와 같이 res1 의 m_ptr 의 주소를 찍어봤는데 와 같이 널포인터(소유권상실)가 아닌 가지고 있던 주소를 계속 가지고 있습니다. 저희가 50번째 줄에 널포인터를 직접 넣기 전에도 소유권 박탈은 안 된 모습인데 move 를 통해 소유권이 상실되는 string 케이스와는 대비가 되는 모습입니다. string 과 달리 사용자 정의 자료형은 이전이나 박탈은 사용자가 직접 정의 해줘야한다는 시각으로 이해하면 될까요? 그리고 move 를 통해 r-value 로 바뀐다고 하는데 그렇다면 바로 위의 예시에서 res1 는 r-value 가 돼서 언뜻 보면 26번줄 이후로는 소멸될 것 같지만 AutoPtr 클래스인 res1 에 테스트 멤버함수를 만들어 호출해봐도 정상적으로 작동이 됩니다. (i'am --> i'm 오타입니다) --> res1 test 멤버함수 --> 32번째 줄 test 멤버함수 호출 이것을 토대로 생각해보면 res1 에 대해 res1 자체를 r-value 로 수정하는 것이 아니라, 자신은 변경되는 것이 아닌 res1 를 r-value 로 가공한 걸 잽싸게 넘겨주고 자신은 바뀌는 것 없이 끝인 개념인가요? 의 경우 위에 해당하는 r-value 복사생성자로 이동합니다. 이렇게 얕은복사가 진행됩니다. ---------------------------------------------------- 이번에는 위에 move 함수를 뺐는데요, 그러면 에 해당하는 l-value 복사생성자가 호출됩니다. 실제로 30번 줄에 의해 와 같은 깊은복사가 일어나게 됩니다. 그래서 r-value 를 써서 소유권 이전 등으로 얕은복사로 리소스를 적게쓰자가 지향점이겠으나 그냥 단순히 아까 깊은복사가 일어나는 l-value 복사생성자 의 내용을 처럼 그냥 얕은복사가 일어나도록 하는 코드로 갈아끼우면 되는 것 아닌가요? 물론 저렇게는 오류가 나서 처럼 const 를 빼주면 정상작동합니다. 위 실행결과 --> 결과도 의도하는 얕은복사가 이루어지는데 이런 방법이 왜 잘못된 건지 알고싶습니다. 질문글이 좀 많이 길어 죄송한 면이 있네요. 항상 친절한 답변 감사합니다. 감사합니다. 3번 질문에 해당하는 코드입니다. <main.cpp> #include "AutoPtr.h" #include "Resource.h" #include <iostream> using namespace std; template<class T> void MySwap(T& a, T& b) { //T tmp = a; //a = b; //b = tmp; T tmp{ std::move(a) }; a = std::move(b); b = std::move(tmp); } int main() { { AutoPtr<Resource> res1(new Resource(1000000)); cout << res1.m_ptr << endl; AutoPtr<Resource> res2 = res1; cout << res1.m_ptr << endl; cout << res2.m_ptr << endl; } return 0; } <AutoPtr.h> #pragma once #include <iostream> using namespace std; template<class T> class AutoPtr { public: T* m_ptr; public: AutoPtr(T* ptr = nullptr) : m_ptr(ptr) { std::cout << "AutoPtr default constructor " << std::endl; } ~AutoPtr() { std::cout << "AutoPtr destructor " << std::endl; if (m_ptr != nullptr) delete m_ptr; } AutoPtr(AutoPtr& a) : m_ptr(a.m_ptr) { a.m_ptr = nullptr; // really necessary? std::cout << "AutoPtr move constructor " << std::endl; } AutoPtr& operator = (const AutoPtr& a) { std::cout << "AutoPTr copy assignment " << std::endl; if (&a == this) // prevent self-assignment return *this; if (m_ptr != nullptr) delete m_ptr; // deep copy m_ptr = new T; *m_ptr = *a.m_ptr; return *this; } AutoPtr(AutoPtr&& a) : m_ptr(a.m_ptr) { a.m_ptr = nullptr; // really necessary? std::cout << "AutoPtr move constructor " << std::endl; } AutoPtr& operator=(AutoPtr&& a) { std::cout << "AutoPtr move assignment " << std::endl; if (&a == this) return *this; if (!m_ptr) delete m_ptr; //shallow copy m_ptr = a.m_ptr; a.m_ptr = nullptr; return *this; } void test() { std::cout << m_ptr << " i'am here " << std::endl; } T& operator*() const { return *m_ptr; } T* operator->() const { return m_ptr; } bool isNull() const { return m_ptr == nullptr; } }; <Resource.h> #pragma once #include <iostream> class Resource { //private: public: int* m_data = nullptr; unsigned m_length = 0; public: Resource() { std::cout << "Resource constructed" << std::endl; } Resource(unsigned length) { std::cout << "Resource length constructed" << std::endl; this->m_data = new int[length]; this->m_length = length; } Resource(const Resource& res) { std::cout << "Resource copy constructed" << std::endl; Resource(res.m_length); for (unsigned i = 0; i < m_length; ++i) m_data[i] = res.m_data[i]; } ~Resource() { std::cout << "Resource destroyed" << std::endl; if (m_data != nullptr) delete[] m_data; } Resource& operator = (Resource& res) { std::cout << "Resource copy assignment" << std::endl; if (&res == this) return *this; if (this->m_data != nullptr) delete[] m_data; m_length = res.m_length; m_data = new int[m_length]; for (unsigned i = 0; i < m_length; ++i) m_data[i] = res.m_data[i]; return *this; } void print() { for (unsigned i = 0; i < m_length; ++i) std::cout << m_data[i] << " "; std::cout << std::endl; } void setAll(const int& v) { for (unsigned i = 0; i < m_length; ++i) m_data[i] = v; } };

  • c++
Echapper4 댓글 2 좋아요 1 조회수 442

1주차 개념 #9 누적합 질문있습니다!

해결됨

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

안녕하세요 선생님 🙂 쉽게 설명해주셔서 항상 감사합니다 ^^ 다름이 아니라 누적합 개념강의에서 선생님께서는 아래의 방식으로 설명해주셨는데요, 0번 인덱스는 비워둠 psum배열을 전역으로 설정하여 값들을 전부 0으로 초기화 psum[1]부터 psum[i - 1] + a[i]를 하시면서 누적합을 계산 아래 방식이 효율적인지 궁금합니다. 0번 인덱스 사용 psum배열에 a배열을 복사 psum[0]은 그대로 둠 psum[1]부터 psum[i] + psum[i - 1] 아래는 선생님께서 설명해주신 승철이가 뇌를 잃어버린 문제에 대한 제 풀이의 전체 코드입니다. #include <iostream> #include <vector> #include <iterator> using namespace std; #define N 8 #define M 3 int A, B; int temp[N]; int main() { int arr[N] = { 1, 2, 3, 4, 5, 6, 7, 8 }; copy(begin(arr), end(arr), begin(temp)); for (int i = 1; i < N; i++) temp[i] += temp[i - 1]; for (int i = 0; i < M; i++) { cin >> A >> B; cout << temp[B] - temp[A - 1] << endl; } return 0; }

  • c++
  • 코딩-테스트
한유태 댓글 1 좋아요 1 조회수 302

애니메이션에 글로벌로 이동할떄 제가이해한게맞는지요

미해결

[게임 프로그래머 도약반] DirectX11 입문

뼈대의 로컬 행렬에 애니메이션변환행렬을 곱하면 글로벌로가는게 제가 이해하는게맞나요? 제가 작업할때 자꾸 뼈의 글로벌행렬에 애니메이션을 곱해서 잘안되었는데 이제보니 로컬행렬에 애니메이션만 곱해줘도 알아서 글로벌로 이동하는 형식인것같더라구용 뼈에 부모행렬을 곱해준것이아닌 로컬행렬에 그냥 애니메이션행렬만 곱해주면 알아서 글로벌로 가는거 맞나요?

  • c++
  • directx
조플레이 댓글 1 좋아요 0 조회수 256

4-A 어디서 틀렸는지 궁금합니다.

미해결

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

http://boj.kr/7effb2a3b4f44d839abcd6ebb1898979 1. 비트마스킹을 이용한 조합 구하기.2. 최소 영양소를 만족하는 조합 걸러내기.3. 그 중 최소 가격 갱신하기.4. 그때의 음식 인덱스 모으기.순으로 풀어갔는데 4에서 막혔습니다. 왜 틀린걸까요?

  • c++
  • 코딩-테스트
최은정 ◡̎ 댓글 2 좋아요 0 조회수 183

이 코드가 왜 틀렸는지 궁금합니다

미해결

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

일단 오류를 찾아서 고쳐 정답이 맞긴 했습니다. 그런데 아무리 봐도 이해가 안돼서 질문글을 남깁니다. 고친부분은 dfs함수에 ret을 전역변수가 아닌 지역변수로 바꾼건데 전역변수로 되어있다해도 함수 시작시 초기화를 해주는데 의미가 있나요? https://www.acmicpc.net/source/76553884

  • c++
  • 코딩-테스트
GRstory 댓글 1 좋아요 0 조회수 162

2-J 질문

미해결

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

안녕하세요 강사님 해당 문제를 강사님과 동일한 방법으로 푸는데 배열 a가 [100][100]이면 틀렸다고 나오더라구요 입력은 s를 통해 받고 저장은 a에다 해서 버퍼 문제가 없을거 같은데 왜 틀리는건가요….?

  • c++
  • 코딩-테스트
재석 강 댓글 1 좋아요 0 조회수 184

차이점을 잘 모르겠습니다.

해결됨

C개발자를 위한 최소한의 C++

주신 프로그램 중 constructSelect.cpp 에서 디폴트 생성자를 지우면 에러가 발생하는데 virtualFunction 에서는 디폴트 생성자가 없어도 동작합니다. constructSelect.cpp 에서 선언 방식이 아닌 new 연산자를 사용해서 해봐도 에러가 발생하고 객체 내에 멤버메서드가 없어서 그런가 해서 멤버를 만들어도 에러가 발생합니다 VirtualFunction 내의 소멸자의 virtual 을 제거해도 이건 잘 작동합니다. 눈으로 봐서는 도저히 차이점을 모르겠습니다.

  • c++
  • microsoft-windows
  • 객체지향
  • 디자인-패턴
내일은 한걸음 더 나아갈거야 댓글 1 좋아요 0 조회수 261

이동생성자 관련

해결됨

C개발자를 위한 최소한의 C++

안녕하세요. 선생님 이동 생성자 강의 내용 중 질문이 있습니다. (아래 코드 참고) delete pnData를 하면, 포인터 변수가 해제되어 pnData = rhs.pnData;를 실행할 수 없는 것이 아닌지 궁금합니다. 실재로는 포인터 값은 그대로고, 가리키는 값(int 0)만 삭제되는 것인가요? 포인터 값은 놔두고 가리키는 값만 없애는 문법은 어떻게 되나요? delete를 안하고, pnData = nullptr; 로만 수정해도 됬을 것 같습니다. class TestData { public: TestData(){ pnData = new int(0); } ... TestData(TestData&& rhs) noexcept{ delete pnData; pnData = rhs.pnData; rhs.pnData = nullptr; } ... TestData& operator=(TestData&& rhs) noexcept{ delete pnData; pnData = rhs.pnData; rhs.pnData = nullptr; } }

  • c++
  • microsoft-windows
  • 객체지향
  • 디자인-패턴
두부 댓글 3 좋아요 0 조회수 338

팩토리얼 함수 질문

해결됨

[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문

처음 메인함수에서 factorial(5)를 실행하면 팩토리얼 함수로 들어가서 return을 n * factorial(n - 1)이잖아요 그러면 5 * factorial(4)니까 함수가 다시실행되서 5 * 4 * factorial(3)이런식으로 계속 호출 되는건가요? 그리고 리턴값이 왜 120이 나오는지 조금 헷갈립니다 처음 factorial(5)를하면 5 * factorial(4)일텐데 이값을 리턴해주는게 아니고 또다시 함수가 호출되는거같은데 혹시 리턴값이왜 120이 나오는지 설명해주실 수 있으실까요 ㅠ

  • c++
킴주니 댓글 2 좋아요 0 조회수 391

7-M 질문드립니다.

미해결

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

안녕하세요 큰돌 강사님 v[y-1][x-1].push_back(z); 로 하면 틀리는 이유를 알고 싶습니다. 입력으로 들어오는 x가 열 아닌가요?? 처음 두 개의 정수는 나무의 위치 (x, y)를 의미하고, 마지막 정수는 그 나무의 나이를 의미한다 답변 미리 감사드립니다 😄

  • c++
  • 코딩-테스트
코테 댓글 1 좋아요 0 조회수 97

no such

미해결

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

zsh: parse error near `\n' (base) mongsil@sinjihwan-ui-MacBookAir ~ % cd /usr/local/include mkdir bits cd bits vi stdc++.h cd: no such file or directory: /usr/local/include (base) mongsil@sinjihwan-ui-MacBookAir bits % clang --version Apple clang version 14.0.3 (clang-1403.0.22.14.1) Target: arm64-apple-darwin22.5.0 Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin (base) mongsil@sinjihwan-ui-MacBookAir bits % clang++ -v Apple clang version 14.0.3 (clang-1403.0.22.14.1) Target: arm64-apple-darwin22.5.0 Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin (base) mongsil@sinjihwan-ui-MacBookAir bits % ~/Library/Application Support/Code/User/settings.json zsh: no such file or directory: /Users/mongsil/Library/Application (base) mongsil@sinjihwan-ui-MacBookAir bits % cd /usr/local/include mkdir bits cd bits vi stdc++.h cd: no such file or directory: /usr/local/include

  • c++
  • 코딩-테스트
몽실 댓글 2 좋아요 0 조회수 220

2 - P 질문

미해결

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

http://boj.kr/ce16c6cbdf114d2dab3f3a8f44c9c285 안녕하세요 강사님 2-P 문제를 강사님의 풀이와는 달리 for 중첩문이랑 처음 입력한 mp배열을 복사해서 풀이할 temp배열을 만들어서 풀어봤는데 몇몇 예제에서 오답이 나와서 질문 드려요ㅠㅡ

  • c++
  • 코딩-테스트
재석 강 댓글 2 좋아요 0 조회수 179

5-O

해결됨

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

큰돌님 안녕하세요.강의 잘 듣고 있습니다. 제 나름대로 고민해보고 풀어 제출하였는데 Segementation fault가 뜹니다.반례를 찾으려고 노력했지만 어느 부분이 문제인지 잘 모르겠습니다.도움 좀 부탁드리겠습니다 ㅠㅠ http://boj.kr/38620660c1684a9f96e362ffbdb9ebc4

  • c++
  • 코딩-테스트
땅콩땡콩 댓글 2 좋아요 0 조회수 259

왜 8 2 10 1 4 6 7 10 이 되나요?

해결됨

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. pair 정렬을 예제로 하신 거 같은데, 출력시켜봤을 때 저는 아래처럼 나오고 있습니다. 1 8 2 2 3 9 4 1 6 4 7 6 9 7 10 10 그런데 강의에는 8 2 10 1 4 6 7 10 이렇게 나와있는데.. 왜 저런 정렬결과가 나오는지 궁금합니다.

  • c++
  • 코딩-테스트
김세준 댓글 2 좋아요 0 조회수 254

모든 경우의수를 구해보는 방식

미해결

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

선생님, 안녕하세요. 괄호추가하기 문제를 풀어보고 있습니다. bfs는 아니고, 큐를 이용하기는 하는데 visited를 이용하지 않게 문제를 풀고 있어요. 전략은 처음에 큐에 식을 넣고, 큐에서 뺄 때, 수식을 계산한다음, 앞에서부터 괄호를 칠 수 있는 부분에 하나씩 괄호를 치고 넘기고. 이걸 반복하고 있습니다. 예를 들면, 9 3+8*7-9*2 를 입력했을 때, 3+8*7-9*2 (3+8)*7-9*2 3+(8*7)-9*2 3+8*(7-9)*2 3+8*7-(9*2) (3+8)*(7-9)*2 (3+8)*7-(9*2) 3+(8*7)-(9*2) 이런식으로 해서 모든 경우의 수를 구해서 비교하는 방식으로 하고 있는데요. 예제는 잘 통과하는데, 제출하면 틀리네요... 한번 봐주시고, 의견주시면 감사하겠습니다. 또, 어떤 반례가 있을까요?? http://boj.kr/0fced5587b8a4c5eb38406042eff5d6d 감사합니다~!

  • c++
  • 코딩-테스트
google_user 댓글 2 좋아요 0 조회수 386

7-D 질문드려요 (메모이제이션)

미해결

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요. 강의 잘듣고있습니다.! 메모이제이션 부분이 이해가 잘 안되서 질문드립니다. dp에 어떤 값이 들어가 있을 때 재귀 호출하지 않고 dp에 담겨져 있는 값을 리턴하는 것에 대한 추가 설명 가능할까요? #include <bits/stdc++.h> using namespace std; int T, W; vector<int> I; int mx = 0; int DP[1001][3][31]; // tree: 트리번호 // cnt: 움직인 횟수 int go(int idx, int tree, int cnt){ int another_tree; if (tree==1) another_tree =2; else another_tree =1; if (idx == T) return 0; // 기저사례 int &ret = DP[idx][tree][cnt]; // 메모이제이션 if (ret) return ret; if (cnt > 0) ret = max(go(idx+1, another_tree, cnt-1), go(idx+1, tree, cnt)) + (tree == I[idx]? 1:0); else ret = go(idx+1, tree, cnt) + (tree==I[idx]? 1:0); return ret; } int main(){ cin.tie(NULL); cout.tie(NULL); ios_base::sync_with_stdio(false); cin >> T >> W; I = vector<int>(T,0); for(int i =0 ; i < T; ++i){ cin >> I[i]; } cout << max(go(0, 2, W-1), go(0, 1, W)); return 0; } dp에 어떤값이 들어가있다는 것은 이미 한번 수행한 이력이 있는 정점이라는 의미로, 더 이상 아래 정점을 탐구할 필요가 없다 라는 의미겠는데.., 완전히 이해를 하지 못하여 질문드려요

  • c++
  • 코딩-테스트
윽쓰욱스 댓글 2 좋아요 0 조회수 268

7-C 질문

해결됨

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

안녕하세요 선생님! 항상 수업 잘 듣고 있습니다 다름이 아니라 저는 dp에 값이 있으면은 사이클이 생긴다는 가정으로 최대숫자를 반환해서 처리하였는데요. 몇 번 시도하였는데 계속 틀림이 뜨네요 ^^; http://boj.kr/56bf4bf2cf4d411fb652d50f54160a7e 그래서 선생님 답안을 보았는데 visited 배열을 따로 만드시고 나중에는 방문 미처리를 해주셨더라고요. 나중에 방문 미처리 해주시는 것이 이해가 잘 안가 왜 그렇게 해주셨는지 궁금합니다! 미리 감사드립니다~ 🙇‍♀

  • c++
  • 코딩-테스트
Raerae 댓글 1 좋아요 0 조회수 169

43번 이진검색에 대한 문의

미해결

it 취업을 위한 알고리즘 문제풀이 입문 (with C/C++) : 코딩테스트 대비

문제가 순서가 바뀌는 것이 불가능하다고 나와있습니다. 이분검색은 정렬된 자료를 이용해서 정렬하는것으로 알고 있는데 만약 곡 시간이 432324 이렇게 나와있다면 이분검색 자체를 못하는것 아닌가요???

  • c++
  • 코딩-테스트
gusckd2007 댓글 1 좋아요 0 조회수 158

2 - O 질문

미해결

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

http://boj.kr/c19ff269920c4179b4e924f04e342db4 안녕하세요 강사님 2 - O 문제를 2 - N 을 보고 비슷하게 풀어보려고 하는데 자꾸 segfault가 떠서 질문 드립니다. 혹시 stk에서 stk.top () 함수가 빈 stk을 참조해서 이런 문제가 발생하나 해서 empty함수를 추가했는데도 같은 결과만 나오네요ㅠ

  • c++
  • 코딩-테스트
재석 강 댓글 2 좋아요 0 조회수 185

매개변수랑 리턴주소 질문

해결됨

[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문

영상에 매개변수랑 리턴주소는 이전함수가 세팅을 해준다고했는데 이게 도저히 무슨말인지 이해가 안갑니다처음 main함수가 스택프레임에 매개변수,리턴값,지역변수 이렇게 할당되고 메인함수안에서 또다른 함수가 실행되면 또 3종세트가 할당되는건 알겠는데 이전함수가 세팅을 해준다는게 무슨의미인가요??

  • c++
킴주니 댓글 1 좋아요 1 조회수 187

인기 태그

인프런 TOP Writers

주간 인기글