Game Develop

간단한 여러 문제들 2 본문

C++/GeeksForGeeks Quiz

간단한 여러 문제들 2

MaxLevel 2022. 7. 9. 04:16

 

이런 유형의 문제가 나올줄은 몰랐는데.. 정답은 C이다.

코드에 <br> 이 있어서 가독성이 좀 별로긴한데, 어쨌든 Test클래스 코드 끝에보면 a;라고 되어있는게 있다. 즉, 클래스를 정의함과 동시에 해당 클래스 인스턴스를 전역변수로 선언해놓은것이다. 그렇기 때문에 전역변수인 Test a의 생성자가 먼저 실행되고, 그다음 메인함수에 진입하여 cout << "Main Started";가 수행되어지는 것이다.

                                                                                                                                                                                                 

 

 

 

 

위 문제의 정답은 표시되어있는것처럼 B이다.

String이라는 클래스에는 const char*라는 데이터타입의 매개변수를 받는 생성자는 있지만, 복사생성자는 작성되어 있지 않는다. 물론 그렇다고 하더라도 main함수의 2번째 줄 String s2 = s1; 에서 컴파일에러는 발생하지 않는다.

왜냐하면 컴파일러가 알아서 복사생성자를 만들어주기 때문이다.

그런데 이 복사생성자는 얕은복사를 수행하는 복사생성자이다.

즉, 복사되어지는 인스턴스의 멤버변수들의 값을 그대로 똑같이 복사해서 생성되어지는 인스턴스에게 넘어가게 된다.

그러면 결국 s1과 s2의 str변수는 같은 힙메모리의 주소를 가리키게 된다. 포인터변수의 주소를 그대로 복사했기 때문이다.

그래서 메인함수에서 s1인스턴스의 힙메모리의 값을 바꾸더라도, s2가 가지고 있는 str변수를 출력했을 때 s1의 str과 똑같은 결과를 출력한다. 약간 클래스의 스태틱 멤버변수같은 느낌이다.

 

                                                                                                                                                                                                 

 

 

이 문제의 정답은 B이다. 다른 글에 관련된 내용을 썼었기 때문에 쉽게 맞췄다.

클래스의 복사생성자를 작성할 때는, 매개변수를 반드시 참조형태로 받아야 한다. 위의 코드에선 &가 생략되었으니 컴파일러단에서 바로 에러를 띄워버린다. 

매개변수를 참조형태로 받지않는다면 p1이 매개변수 p로 복사가 되는 과정에서 또 복사생성자가 호출된다. 이게 무한히 반복된다. 복사생성자를 호출하는 과정에서 복사생성자를 호출하고 그 과정에서 또 복사생성자를 호출하게 되는것이다.

그렇기 때문에 컴파일러가 에러를 뱉는것이다.

 

                                                                                                                                                                                                 

 

A와 B는 각각 참조형변수와 상수형변수인데, 알다시피 둘 다 반드시 선언과 동시에 초기화가 되어야 하는 변수들이다.

다른 변수처럼 int a; 선언 후, a = 0; 이런식은 성립되지 않는다. 

그렇기 때문에 클래스의 멤버변수로 상수형,참조형 변수를 보유하고 싶을 경우 반드시 초기화리스트를 이용하여 값을 초기화 해줘야 한다. C는 기본생성자가 없는 데이터타입의 멤버변수를 초기화해야할 경우인데, 이 또한 초기화리스트를 사용해야한다. 관련되서 정리한 글이 있기 때문에 달아놓는다.

https://maxlevel-trace.tistory.com/74

 

초기화리스트(Initilizer List)를 사용해야하는 경우.

초기화리스트를 사용해야 하는 경우 2가지와 사용할 경우 이점을 설명해보겠다. 1. 클래스에서 상수형변수, 참조형변수를 멤버변수로 보유해야 할 경우. 상수형 변수와 참조형 변수는 둘 다 반

maxlevel-trace.tistory.com