해결된 질문
작성
·
388
1
안녕하세요.
강의에 나온 대로 코드를 조금 변형해서 짜는 중인데 namespace에 걸린 함수를 어떻게 불러오느냐에 따라 값이 달라서 궁금해서 질문드립니다.
#include <iostream>
using namespace std;
namespace work1
{
int a = 1;
int doSomething()
{
a += 3;
return a;
}
}
namespace work2
{
int a = 2;
int doSomething()
{
a += 5;
return a;
}
}
int main()
{
cout << "<First Try> \nwork1_a: " << work1::a << endl;
cout << "\nwork2_a: " << work2::a << endl;
cout << "\nwork1_doSomething: " << work1::doSomething << endl;
cout << "\nwork2_doSomething: " << work2::doSomething << endl;
cout << "\nwork1_doSomething(): " << work1::doSomething() << endl;
cout << "\nwork2_doSomething(): " << work2::doSomething() << endl;
work1::a;
work1::doSomething;
work2::a;
work2::doSomething;
cout << "\n<Second Try> \nwork1_a: " << work1::a << endl;
cout << "\nwork2_a: " << work2::a << endl;
cout << "\nwork1_doSomething: " << work1::doSomething << endl;
cout << "\nwork2_doSomething: " << work2::doSomething << endl;
cout << "\nwork1_doSomething(): " << work1::doSomething() << endl;
cout << "\nwork2_doSomething(): " << work2::doSomething() << endl;
return 0;
}
이걸 출력하면
<First Try>
work1_a: 1
work2_a: 2
work1_doSomething: 0056107D
work2_doSomething: 00561145
<Second Try>
work1_a: 4
work2_a: 7
work1_doSomething: 0056107D
work2_doSomething: 00561145
work1_doSomething(): 7
work2_doSomething(): 12
이렇게 나옵니다.
doSomething에서 ()를 붙이지 않은 경우에는 16진수로 나오고, 코드를 돌릴 때마다 계속 바뀌던데 이거는 주소값 인가요? 그게 아니라면 왜 이렇게 나오는 지 궁금합니다.
그리고 second try에서는 work1_a와 work2_a의 값이 4와 7이 되어서 doSomething()의 값도 7과 12로 변하는데, 이는 First try에서
cout << work1::doSomething() << endl;
cout << work2::doSomething() << endl;
을 하면서 a의 값이 4와 7로 변했기 때문인 것으로 보입니다.
그런데 main 함수 내에서
work1::a;
work1::doSomething;
work2::a;
work2::doSomething;
을 쓰고 second try 이하를 출력하나, 이를 빼고 바로 second try 이하 부분을 출력하나 같은 결과(a값이 각각 4와 7)인데,
그렇다면 메인 함수에서 단순히 work1::a; work1::doSomething;을 쓸 때에는 어떤 효과를 가지게 되나요?
메인 함수 내에서 work1::doSomething; 을 쓴다면 일종의 정의(definition)가 되는 것이고, work1:doSomething()을 하면 그때부터 함수를 사용하는 것이라고 봐도 될까요?
답변 4
3
namespace 내에서 가장 바깥에 선언된 변수들은 "전역 변수"입니다. global variable 맞습니다! 그래서 scope는 프로그램 전체입니다. (namespace 자체 또한 함수 내부 이런 곳이 아닌 전역 공간에서만 선언 가능합니다.)
이름은 a로 같더라도 work1::a 와 work2::a 는 다르듯이, 이름은 철수로 같더라도 201호 사는 철수와 202호 사는 철수가 다르듯이 같은 이름의 변수라도 속한 네임스페이스에 따라 구분 되도록 하는 것이 네임스페이스가 하는 일입니다.
프로그램 규모가 커지면 수 많은 변수들이 만들어질 것이고 일일이 이름 같은 변수를 짓게하지 않도록 조심하면서 새로운 변수의 이름을 짓는 것이 쉬운 일은 아닐 것입니다. 이럴때 namespace로 전역변수들에게 약간의 그룹화를 해주는 것이 이러한 문제에 도움이 되겠습니다.
사실 namespace 없이 선언되는 전역변수도 사실은 이름없는 namespace 에 속해 있는 것이나 마찬가지입니다. 이름 없이 ::a 을 호출해도 정상적으로 3이 출력되는 것을 확인할 수 있습니다.
work1의 a나 work2의 a 나 둘 다 전역 변수입니다. 네임스페이스로 두 전역변수를 work1::a 과 work2::a 로 구분지을 수 있게 되었다는 정도로 생각해주시면 될 것 같습니다.
함수 또한 마찬가지입니다.
2
안녕하세요!
- 주소값 맞습니다. 함수의 이름만 출력하면 그 함수의 주소가 출력됩니다. 함수의 이름 그 자체에 함수의 주소가 담겨 있기 때문입니다. 이 부분은 앞으로 함수 포인터 관련 강의에서 배우게 되실거에요.
- 각각의 doSomething() 의 a += 3, a+= 5 를 통해 각각 4 와 7 로 변한 것이 맞습니다. second try 이하 부분인 두 번째 doSomething() 실행은 첫 번째 doSomething() 실행으로 각각 4, 7로 변경된 a 값을 가지고 a += 3, a+= 5 을 각각 진행하게 되서 최종적으로 7 과 12 가 되었습니다.
- 이 부분은 아무 효과 없습니다.
마치 위 코드 사진에서의 c; 와 같아요! 그냥 변수만 달랑 적으면 아무 효력이 있지 않습니다.
- "메인 함수 내에서 work1::doSomething; 을 쓴다면 일종의 정의(definition)가 되는 것이고, work1:doSomething()을 하면 그때부터 함수를 사용하는 것이라고 봐도 될까요?"
👉 정의 아닙니다. 마치 제가 위에서 예시로 든 int c; 로 정의가 기존에 되었던 c를 가지고 c; 이렇게 써주는 것은 아무 효력이 없는 것 처럼 work1::doSomething; 은 단순히 work1 네임스페이스에 이미 정의 되어 존재하는 doSomething 함수의 이름을 적어주고 세미콜론 찍어준 것 뿐입니다.
👉 네. 아마 이 부분은 위에서도 말씀드렸지만 함수 포인터 부분에서 자세히 알게되실거에요! 함수 이름인 doSomething 은 함수의 주소를 담고 있는 문장이라고 볼 수 있고 doSomething() 은 함수를 실행하는 문장입니다.
0
질문을 보고 갑자기 들은 생각인데, namespace에서 정의된 변수들은 scope이 어떻게 되나요? 위의 프로그램을 보면 global variable 처럼 사용되는 것 같은데....
0