Game Develop

간단한 여러 문제들 1 본문

C++/GeeksForGeeks Quiz

간단한 여러 문제들 1

MaxLevel 2022. 7. 7. 21:57

 

위 문제의 정답은 D이다. 왜일까? 아마 C라 생각한 사람도 있을 수 있다.

하지만 C++에서 Class는 기본적으로 따로 명시하지 않을 경우, 접근제한자는 private이다. (struct는 public)

그렇기 때문에 위의 Point클래스에서의 생성자는 private이고 main함수에서 저렇게 호출 할 수 없다.

그래서 당연히 컴파일단계에서 에러가난다.

 

                                                                                                                                                                                                 

 

위 문제의 정답은 C이다. t1은 저 선언만으로 스택에 Point만큼의 크기를 할당받았지만, t2는 그냥 객체의 주소를 담는 포인터변수일 뿐이다.

 

                                                                                                                                                                                                 

 

 

 

아마 C++문법이나 생성자호출에 대해 따로 공부하지않은 사람은 슬슬 헷갈릴 수도 있다.

위 문제의 정답은 C이다.

앞서 말했듯이, 포인터변수는 선언하더라도 생성자가 호출되지 않는다.

new연산자를 통해 힙메모리에 공간을 할당할 때 호출되는데, 그렇기 때문에 아래와 같다.

 

Point *t1, *t2; // 생성자 호출 x.

t1 = new Point(); // 기본생성자 호출.

t2 = new Point(*t1); // 복사생성자 호출.

Point t3 = *t1; // 복사생성자 호출. *t1의 값으로 복사생성(생성과 동시에 초기화) 했기 때문.

Point t4; // 기본생성자 호출.

t4 = t3; // 대입연산자 호출. 본 문제와는 상관없다.

 

                                                                                                                                                                                                 

 

 

위 문제는 C++의 중괄호 초기화를 아냐,모르냐의 문제같다. 나는 이 문제를 보고 처음 알았다.

일단 정답은 C다.

본문처럼 대입연산자 뒤에 중괄호로 저렇게 초기화해도 되고 아래처럼 대입연산자 없이 해도 된다.

 

struct Point
{

     public:
          int t;
          string str;

          char c;


};

int main()
{
     Point a{ 10,"temp"}; // OK.

     Point b{10}; // OK.

     Point c{"temptemp"}; // No.
     cout << a.t << endl;
}

 

멤버변수가 선언한 순서대로 값을 기입하면 되고, 멤버변수 선언 순서만 맞는다면 뒤에껀 생략해도 괜찮다.

Point a,b는 멤버변수 3개 전부 다 기입을 안했더라도 순서대로 작성했기 때문에 컴파일에러가 발생하지 않지만,

Point c는 멤버변수중 제일 첫번째 데이터타입인 int형이 아니라 string형을 기입했기 때문에 에러가 발생한다.

 

                                                                                                                                                                                                 

 

 

위 문제의 정답은 C이다. 해당 코드를 실행하면 Point p1; 부분에서 컴파일에러가 발생한다.

클래스를 생성했을 때 따로 생성자를 명시하지 않으면, 컴파일러는 알아서 기본생성자를 생성해준다.

단, 본문과 같이 복사생성자처럼 다른 생성자를 한개라도 명시해 놓았다면, 컴파일러는 기본생성자를 생성하지 않는다.

결국 컴파일 시 기본생성자가 없기 때문에 Point p1;에서 기본생성자를 호출하려해도 호출할 생성자가 없어서 에러가 발생하게된다. 

만약 기본생성자가 있었다고 가정하면, 답은 A가 된다. 나같은 경우 x,y값에 -858993460 값이라는 쓰레기값이 출력됐다.

 

                                                                                                                                                                                                 

 

 

위 문제의 정답은 B이다. 위 문제는 기본적인 복사생성자(얕은복사)를 컴파일러가 알아서 생성해주는걸 아느냐 모르느냐를 묻는 문제같다. 알아서 생성해주기 때문에 답은 B가 맞다. 

물론 각 멤버변수의 값을 그대로 복사하는 얕은복사이기 때문에 포인터멤버변수가 가르키고 있는 힙메모리의 값을 복사하려면, 따로 깊은복사로 복사생성자를 만들어 줘야 한다.

 

                                                                                                                                                                                                 

 

답은 보다시피 B이다. malloc은 new와 달리 생성자를 호출하지 않는다. 생각해보면 c에는 클래스개념이 없다.

그러면 혹자는 'C언어에 Class는 있어도 구조체는 있으니까, 내부에 생성자나 기타등등 선언하면 되지 않나?' 라고 생각할 수 있지만, C의 구조체와 C++의 구조체는 다르다. C의 구조체 내부에는 함수선언이 안된다.