• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

레퍼런스 관련 질문이 있습니다.

21.01.28 22:40 작성 조회수 203

0

class frac {

private:

int _nume;

int _deno;

public:

frac(const int &a,const int &b){

_nume = a;

_deno = b;

}

void print() {

cout << &_nume << endl;

}

};

int main() {

int a = 5;

frac my_frac(a,6);

cout << &a << endl;

my_frac.print();

return 0;

}

frac 클래스의 생성자에서 int a를 레퍼런스로 받아와 _nume에 대입? 시킨 후 클래스 내의 print 함수로 nume의 주소값을 출력했을때 int a의 주소와 다른값이 나옵니다 

레퍼런스가 선언될때 동시에 초기화를 해주면 같은 주소값을 가질수 있다고 알고있는데 저렇게 클래스 내의 private에 선언돼어 있을 경우에는 같은 주소값을 가지게 할 수 없나요?

답변 1

답변을 작성해보세요.

3

안소님의 프로필

안소

2021.01.28

안녕하세요.

생성자가 호출되면서, 생성자의 매개변수인 a에서 main 함수에서 넘긴 a를 참조하게 됩니다. 그러니 호출된 생성자의 인수로 넘겨진 main 함수에서의 a 를 참조하게 되므로 main 함수의 a와 생성자 매개변수인 a의 주소는 같습니다. 

그러나 _nume은 참조 변수가 아닌 그냥 int입니다!  그러니 _nume은 이 a의 값을 복사 받은 '사본'일 뿐입니다. 따라서 _nume 과 a는 당연히 주소가 다를 수 밖에 없습니다. int a = 2; int b = a; 하면 b에는 2 값이 대입되지만 a와 b는 서로 다른 존재죠.(즉 주소가 다름) 이와 마찬가지인 것입니다. _nume은 그냥 int 변수일 뿐이기 떄문에 _nume = a 는 그냥 a의 값을 복사 받은 a 의 사본이 될 뿐이에요. 

main 에서 넘긴 a와 같은 주소를 가지는 것은 생성자의 매개 변수인 const int &a의 a입니다. _nume이 아닙니다.

말씀하신 것처럼 레퍼런스는 참조할 대상을 지정해주는 작업을 선언할 때 해주어야 합니다. 참조 변수라면 선언과 동시에 어떤 변수를 참조할지 대상이 초기화로 정해져야 하는데 _nume이 객체 바깥에 있는 특정 대상을 참조하도록 아래와 같이 선언해주실 것이라면 아래 사진과 같이 이 멤버변수 선언 과정에서 이루어져야 한다는 얘기인데 이 클래스 멤버 선언 과정에서 객체 바깥의 main함수의 a를 알리는데 애로사항이 있습니다. private이냐 public이냐와는 상관이 없습니다. 그리고 객체지향프로그래밍에서 굳이 객체 메모리 내부의 멤버 변수가 객체 바깥에 있는 변수와 같은 주소값을 갖도록 만들어야할 필요성은 없다고 생각합니다. 

(덧붙여서 질문 올려주신 출처 강의가 <8.4 생성자 초기화 목록>이신데 <8.3 생성자> 강의에 올려주셨어야 했을 것 같아요!)