작성
·
25
1
friend 키워드를 이용해 연산자 <<를 오버로딩한 함수를 정의할때, 전역변수임에도 불구하고
클래스 내부에 함수에 대한 정의까지 하는 이유를 잘 모르겠습니다.
클래스 내부에는 함수에 대한 선언만 하고 정의는 클래스 바깥에 하지 않는 이유가 있을까요?
강의중에 강사님께서도 몇번 헷갈리실정도로 가독성에 안좋고 처음 제가 이 내용을 학습할때도 굉장히 헷갈릴정도로 혼동을 유발하는것 같은데
이런 방식을 써야하는 이유가 있는지 궁금합니다
답변 2
1
안녕하세요, 질문&답변 도우미 durams입니다.
질문자님께서는 연산자 오버로딩의 정의를 클래스 내부에 두는 것보다 외부에 두는 것이 가독성에 더 좋지 않냐고 여쭤보시는 것 같습니다.
저는 가독성이라는 단어에 대해서는 생각해 볼 여지가 있다고 생각합니다. 먼저 질문자님께서 말씀하신 가독성이 좋지 않다는 말은, 프로그래머가 코드 작성 시 friend
로 클래스 내부에 정의된 함수를 멤버 함수로 착각할 수 있다는 의미로 생각됩니다. 언급하셨듯이, 영상에서도 교수님께서 잠시 헷갈려하는 순간이 있으셨습니다.
하지만 다르게 생각해볼 수도 있습니다. 코드를 읽는 입장에서는 어떠한 클래스에 대해 동작하는 <<
/>>
연산자 오버로딩의 정의가 해당 클래스의 내부에 있는 경우 훨씬 깔끔하게 읽힐 수도 있습니다. 클래스 내부에 정의를 작성한다는 것 자체가 해당 클래스에 종속적인 기능이라는 의미를 내포하기 때문입니다.
즉, 함수 자체는 global이지만 그 semantic을 고려해서 함수 내부에 정의를 하는 것입니다. 이렇게 하면 해당 클래스에서 사용하는 기능이라는 의미가 더 강해지고, 코드를 읽는 사람으로 하여금 '이 클래스에서 사용하는 함수구나'라는 인상을 더 심어줄 수 있습니다. 이러한 문제의 경우에는 정답이 정해져있기 보다는, 가장 읽기 쉽고 다른 사람이 봤을 때 이해가 잘 될 법한 코드를 작성하는 것이 좋습니다. 실제로 말씀하신 두 방법은 동작에 있어 차이가 없으니까요.
대신 만약 클래스의 선언과 정의를 분리해서 각각 헤더 파일과 .cpp
파일에 작성하는 경우에는 말씀하신 것처럼, 헤더에 있는 클래스 선언에 friend
선언을 두고, .cpp
파일에 정의를 작성하는 것이 일반적입니다.
물론 말씀하신 것처럼 코드 작성에 있어 실수할 가능성도 있습니다만, 대신 이러한 것들은 Visual Studio의 Intellisense와 같은 문법 검사 기능 등에서 잘 검사해주는 부분이기도 합니다. 이러한 기능들을 잘 사용하신다면 멤버/비멤버 함수의 구분에 있어 혼동이 적어지실 거라고 생각합니다.
여기서부터는 강의의 내용을 벗어나는 내용이지만, 개인적으로 알아보던 중 알게 된 내용을 말씀드립니다. 이 내용에 대해서는 참고로만 보시고, 메모해두셨다가 나중에 궁금해졌을 때 찾아보시는 걸 추천합니다.
두 경우는 똑같아 보이지만, name lookup을 하는 과정이 다르다고 합니다. name lookup이란 컴파일러가 수행하는 작업으로, 변수/함수/클래스 등의 이름을 만났을 때 이를 선언과 연결시키는 작업입니다. name lookup은 qualified lookup과 unqualified lookup 두 가지로 나뉘며, 특수한 형태로 ADL이 존재합니다.
Qualified lookup : ::
연산자를 사용해서 특정 네임스페이스/클래스의 멤버를 찾는 방식
Unqualified lookup : ::
연산자 없이 그냥 이름을 사용한 경우. 현재 스코프에서부터 상위 스코프로 올라가며 찾는 방식
ADL(Argument Dependent Lookup) : 함수의 인자 타입을 보고, 해당 타입이 속한 네임스페이스에서 추가로 탐색하는 방식
정의를 클래스 내부에 둔 경우에는 namespace가 가려지게 되어 일반적인 namelookup으로 찾을 수 없어 ADL을 사용하고, 외부에 둔 경우에는 qualified lookup을 사용하여 찾는다고 합니다.
아래는 관련 링크입니다.
말씀드렸듯이, 위 내용은 기술적으로 깊은 내용인 동시에 질문주신 내용과는 거리가 있기에, 먼저 말씀드렸던 답변 전반의 내용을 중요시해주신다면 감사하겠습니다.
질문자님께서 원하시는 답변이 아니라면, 다시 질문해주세요. 성심껏 답변드리겠습니다.
0
안녕하세요, 인프런 AI 인턴입니다. 윤지환님께서 질문하신 friend 키워드를 사용한 연산자 오버로딩에 대한 의문에 대해 설명드리겠습니다.
C++ 언어에서는 클래스의 private 멤버에 접근하기 위해 특정 기능을 사용하는 경우가 있습니다. friend 키워드는 그러한 목적으로 사용됩니다. 연산자 <<의 오버로딩은 출력 스트림(예: std::ostream)을 사용하여 클래스의 객체를 출력할 수 있게 도와줍니다.
** 클래스 내에서의 정의 이유**:
관련 답변:
클래스 외부에서 구현 가능 여부:
윤지환님께서 추가적으로 궁금한 점이 있거나 더 깊이 있는 설명이 필요하시다면, 다시 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.