inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

15.7 순환 의존성 문제와 std::weak_ptr

이 수업 마지막에 lock() 이용해서 getname 하는 부분 질문입니다.

479

seungmin38

작성한 질문수 11

2

#include <iostream>
#include <memory>
#include <string>

class Person
{
	std::string m_name;

	//std::shared_ptr<Person> m_partner;
	std::weak_ptr<Person> m_partner; // ⭐⭐⭐

public:
	Person(const std::string& name) : m_name(name)
	{
		std::cout << m_name << " created\n";
	}

	~Person()
	{
		std::cout << m_name << " destroyed\n";
	}

	friend bool partnerUp(std::shared_ptr<Person>& p1, std::shared_ptr<Person>& p2)
	{
		if (!p1 || !p2)
			return false;

		p1->m_partner = p2;
		p2->m_partner = p1;

		std::cout << p1->m_name << " is partnered with " << p2->m_name << "\n";

		return true;
	}

	const std::shared_ptr<Person> getPartner() const // ⭐⭐⭐
	{
		return m_partner.lock(); // ⭐⭐ lock 함수 실행
	}

	const std::string& getName() const
	{
		return m_name;
	}
};
int main()
{
	auto lucy = std::make_shared<Person>("Lucy");
	auto ricky = std::make_shared<Person>("Ricky");

	partnerUp(lucy, ricky);

	std::cout << lucy->getPartner()->getName() << std::endl;
	return 0;
}

수업 중 마지막 코드 입니다.

 

std::cout << lucy->getPartner()->getName() << std::endl;

이 부분을 통해 Ricky를 출력하게 되는 과정을 다음과 같이 해석했는데 제가 해석한게 맞는지 확인 부탁드립니다.

lucy->getPartner() 에서 lucy객체의 멤버 변수이자 weak_ptr인 m_partner의 lock()함수 호출

한편 m_partner를 ricky라는 객체 역시 소유하고 있음(partnerUp함수로 인해)

따라서 lock()는 ricky객체를 shared_ptr로 임시 변환해서 리턴

오로지 weak_ptr로는 소유하고 있는 객체의 멤버에 접근하는 것이 불가능했지만 lucy->getPartner() 이런 방식으로 ricky라는 객체를 리턴하였고 따라서 ricky라는 객체의 맴버함수 및 맴버변수에 접근할 수 있게 되었다.


1.저 코드 한줄에 대한 제 해석이 맞는지 확인 부탁드리고

2.혹시 lock()함수가 lucy객체의 멤버 함수지만 리턴한건 해당 객체의 멤버 변수(여기선 m_partner)를 해당 객체인 lucy객체와 공동으로 소유중인 ricky객체를 리턴했는데

그렇다면 lock함수는 자신이 속한 객체 이외에 공동으로 소유중인 또 다른 객체를 리턴한다
로 이해해도 되겠습니까?

 

답변 부탁드립니다. 감사합니다.

 

c++ weak_ptr lock함수 스마트포인터

답변 1

1

Soobak

안녕하세요, 답변 도우미 Soobak 입니다. 😀

또 뵙네요! 반갑습니다. 😁

std::cout << lucy->getPartner()->getName() << std::endl;

질문 1. - 이 부분을 통해 Ricky를 출력하게 되는 과정을 다음과 같이 해석했는데 제가 해석한게 맞는지 확인 부탁드립니다.

  • lucy->getPartner() 에서 lucy객체의 멤버 변수이자 weak_ptr인 m_partner의 lock()함수 호출

    : 네, 맞습니다. 😀 lucy->getPartner()에서 lucy 객체의 멤버 변수인 m_partner가 참조하는 weak_ptrlock() 함수가 호출됩니다.

  • 한편 m_partner를 ricky라는 객체 역시 소유하고 있음(partnerUp함수로 인해)

    : 네, 맞습니다. 😁 partnerUp() 함수를 통해 서로 파트너 관계가 형성되었기 때문에, lucy 객체의 m_partner 멤버 변수는 ricky 객체를 가리키는 weak_ptr를 저장하고 있고, 동시에 ricky 객체의 m_partner 멤버 변수 또한 lucy를 가리키는 weak_ptr를 저장하고 있습니다. (두 변수는 상호 참조 관계를 통해 연결되어 있습니다.)

  • 따라서 lock()는 ricky객체를 shared_ptr로 임시 변환해서 리턴
    : 네, 맞습니다. lock() 함수는 해당 weak_ptr 이 가리키는 객체에 대한 shared_ptr 를 생성하여 반환합니다. 위 코드에서는 lucy->getPartner()에서 호출되는 lock() 함수가 lucy 객체의 m_partner 멤버 변수가 가리키는 ricky 객체에 대한 shared_ptr 를 임시로 생성하고 반환하는 것이겠죠!

질문2. 혹시 lock()함수가 lucy객체의 멤버 함수지만 리턴한건 해당 객체의 멤버 변수(여기선 m_partner)를 해당 객체인 lucy객체와 공동으로 소유중인 ricky객체를 리턴했는데 그렇다면 lock함수는 자신이 속한 객체 이외에 공동으로 소유중인 또 다른 객체를 리턴한다 로 이해해도 되겠습니까?

: 음, 우선 lock() 함수가 lucy 객체의 멤버 함수라는 것은 다소 애매한 표현인 것 같습니다. lucy 객체의 m_partner 변수가 std::weak_ptr<Person> 타입이므로, lock() 함수는 해당 std::weak_ptr 변수에서 호출되는 것입니다.
뒷 부분의 설명 부분은 옳게 학습하신 것 같습니다. 👍 lucy->getPartner() 에서 lock() 함수를 호출하면, lucy 객체의 m_partner 변수가 가리키는 ricky 객체에 대한 share_ptr 을 임시로 생성하고 반환합니다. (공동으로 소유하고 있는 주체는 lucyricky 객체의 m_partner 변수이며, 해당 변수가 서로 상대방을 가리키는 weak_ptr 타입으로 저장되어 있습니다.)

음, 답변이 되셨길 바라며, 혹시 제가 질문을 잘못 이해한 것이라면 편하게 추가로 댓글 부탁드리겠습니다.
매일 꼼꼼하게 학습하시는 모습이 멋있으세요 ! 👍👍👍그리고 매일 점점 발전하시는 모습이 느껴져서 인상깊네요!!
언제든지 또 편하게 질문 남겨주세요!!!! 화이팅!!!!!

1

seungmin38

아 이해했습니다.감사합니다.

추가적으로,
위의 코드의 경우엔 같이 공유중인 객체가 본 객체 이외에 1개뿐이라
lock함수가 공유중인 객체를 1개만 호출했는데
혹시 그러면 공유하는 객체가 3개,4개 등등이 될 경우
lock함수를 쓰면 여러개의 객체에 대한 shared_ptr 생성하고 반환하나요??

1

Soobak

안녕하세요, 답변 도우미 Soobak 입니다.

편하게 댓글 남겨주셔서 감사합니다.

추가 질문 - 위의 코드의 경우엔 같이 공유중인 객체가 본 객체 이외에 1개뿐이라 lock함수가 공유중인 객체를 1개만 호출했는데 혹시 그러면 공유하는 객체가 3개,4개 등등이 될 경우 lock함수를 쓰면 여러개의 객체에 대한 shared_ptr 생성하고 반환하나요??
: 음... 아닙니다. 여러 개의 객체를 참조하기 위해서는 여러 개의 std::weak_ptr 변수를 사용해야 합니다. 즉, 질문자님께서 말씀하신 lock() 함수를 쓰면 여러 개의 객체에 대한 shared_ptr 이 생성되고 반환되는가? 는 아니라고 말씀드리는 게 적절할 것 같습니다.

주로 특정 자료구조에 여러 개의 변수들을 담아 관리하는데요, Microsoft- How To: Create and use weak_ptr instances 의 예제 코드를 보시면 보다 이해하시기 편하실 것 같습니다.

또한, 아직 스마트포인터와 '소유권' 등에 대한 개념에 혼란이 있으시다면, 예전 답변도우미께서 자세하게 답변해주신 글 을 참고해보시는 것도 추천드립니다. 👍

답변이 되셨길 바라며, 제가 질문을 잘못 이해하였거나, 추가적인 궁금증이 있으시다면 편하게 또 댓글 남겨주시면 감사하겠습니다. 화이팅! 😁

1

seungmin38

아 이해했습니다. weak_ptr 포인터 변수에 대한 공유는 두개의 객체가 공유가능하고
3개의 객체가 하나의 weak_ptr 포인터 변수에 대한 공유는 불가능하며 그렇기에 "여러 개의 객체를 참조하기 위해서는 여러 개의 std::weak_ptr 변수를 사용해야 합니다" 라고 답변 주신거죠?

 

자세한 답변 감사합니다!!

강의자료는 어디서 받을 수 있죠?

1

36

2

교재 있나요?

1

142

2

11:11 부근에 Something::temp와 Something::getValue의 앞에 &를 붙이는 이유가 뭔가요? (함수 이름은 포인터(주소)가 아닌가요?)

1

95

3

using namespace std; 선언 후에 std::를 하는 이유가 궁금합니다

1

107

2

cstr직접구현

0

119

3

BubbleSort

1

80

2

숙제 마지막 부분

1

80

2

강의와 똑같이 진행했는데 링킹 에러가 발생합니다.

1

97

2

수업할때 레퍼런스로 사용하는 도서는 어떤 도서인가요??

1

165

2

공변반환형 관련 문의 드립니다.

1

92

2

170강 유니크 포인터에대해 질문있습니다

1

82

1

섹션 5 퀴즈의 답이 이상합니다

1

86

2

이중포인터와 배열이 이해가 안됩니다.

1

161

2

5분 17~5분 34초 객체 잘림 질문

1

80

1

Resource.h 코드 알려주세요

1

74

1

char name[] 배열의 길이와 관련해 일부 궁금점이 생겨서 질문합니다

1

96

2

화면좌측 숫자 보이기

1

116

1

화면 좌측 숫자 보이기

0

68

1

처음 c++ 수강하려는데요. 비주얼스튜디오 2022 다운로드해서 설치하면 되는건가요??

1

139

3

46강 string 버퍼 질문입니다

1

82

2

프로그래머스 수열과 구간 쿼리 2 문제 질문입니다.

1

126

2

[] 범위 검사시 assert 사용 관련 질문

1

92

2

Lecture 클래스 멤버변수 명명 관련

0

94

2

프로그래머스의 대소문자 바꿔서 출력하기 문제를 푸는데요

0

76

1