티스토리 뷰

※잘못된 부분이 있으면 댓글로 알려주세요. 


이 포스팅은 지난 금요일(11/27)에 학과단톡방에 올라온 질문에 답변을 드린 내용을 정리한 것입니다. 

#include <iostream>
#include <cmath> 
using namespace std;

const double PI = 3.141593;

struct C2dType { // 2차원 좌표 구조체
    double x, y;
};

class CircleClass { // 원 클래스
    C2dType center;   // 중심좌표
    double radius;    // 반경

public:
    void init(double cx, double cy, double r) {    // 중심 (cx, cy), 반경 r로 원을 초기화
        center.x = cx;
        center.y = cy;
        radius = r;
    }
    // 원 면적 계산
    double area() const {
        return radius * radius * PI;
    }
    bool chkOverlap(const CircleClass& c) const {
        double dx = center.x - c.center.x;
        double dy = center.y - c.center.y;
        double dCntr = sqrt(dx * dx + dy * dy);
        return dCntr < radius + c.radius;
    }
    void display() const {    // 원 객체의 정보 디스플레이 
        cout << "중심 : (" << center.x << ", " << center.y << ") ";
        cout << "반경 : " << radius << endl;
    }
};

int main() {
    CircleClass c1, c2;
    c1.init(0, 0, 10); // 중심(0, 0), 반경10으로 초기화
    c2.init(30, 10, 5); // 중심(30, 10), 반경5로 초기화

    cout << "원1" << endl;
    c1.display();
    cout << "원1의 면적 : " << c1.area() << endl;
    cout << "원2" << endl;
    c2.display();
    cout << "원2의 면적 : " << c2.area() << endl;

    if (c1.chkOverlap(c2))     // 두 원의 중첩 여부 출력
        cout << "두 원은 중첩됩니다" << endl;
    else
        cout << "두 원은 중첩되지 않습니다" << endl;
    return 0; 
}

이상은 C++ 프로그래밍 교재 53~54페이지에 걸쳐 구조체와 클래스를 설명하는 부분입니다. 

    bool chkOverlap(const CircleClass& c) const {
        double dx = center.x - c.center.x;
        double dy = center.y - c.center.y;
        double dCntr = sqrt(dx * dx + dy * dy);
        return dCntr < radius + c.radius;
    }
    if (c1.chkOverlap(c2))     // 두 원의 중첩 여부 출력
        cout << "두 원은 중첩됩니다" << endl;
    else
        cout << "두 원은 중첩되지 않습니다" << endl;

 

질문하신 학우님께서 궁금해하신 내용은(제가 이해하기로는)다음과 같았습니다. 

1) bool 함수에는 왜 변수가 하나뿐인지 

2) if함수에서 괄호 안의 조건이 무슨 뜻인지 

 

이하 '더보기'로 답변을 정리하겠습니다. 

 

더보기

1) 클래스를 선언하면 클래스 내의 객체에 각각 함수를 적용할 수 있으며 점 표기법(.)으로 객체에 접근 가능합니다. 위의 bool 함수에서는 CicleClass 내의 객체가 갖는 값을 상수로 불러오도록 선언되어 있습니다. 

2) bool 함수는 0과 1로 return하고, 아래의 if문에서는 조건문이 c1.chkOverlap(c2)로 걸려 있으므로 이 값이 1이면 참true이므로 원이 중첩된다고 출력하는 조건을, 0이면 거짓false이므로 중첩되지 않는다고 출력하는 조건을 달성합니다. 

 

학우님은 여전히 c1.chkOverlap(c2)가 무슨 뜻인지 이해가 되지 않고, 제 설명대로라면 c1.chkOverlap(c2)와 c2.chkOverlap(c1)의 값은 달라져야 하는 것 아니냐고 추가로 질문하셨습니다.

 

더보기

c1.chkOverlap(c2)는 구조체 변수 c1에 chkOverlap(c2) 연산을 적용했을 때의 값을 묻는 것이고, c1과 c2의 순서를 바꾼다고 해서 답이 달라지지 않는 것은 두 원의 좌표 자체가 달라지지 않았기 때문입니다. 그러니 c1과 c2 중 어느 쪽을 변수로 넣는다고 해도 값이 동일할 수밖에 없습니다. 다음과 같이 직접 그려 보면 직관적으로 이해할 수 있습니다.

goodnote에서 제공하는 모눈종이 서식은 좌표를 간단하게 그릴 때 매우 편리합니다.

학우님께서 마지막으로 하신 질문은 return dCntr < radius + c.radius; 구문의 의미에 대해서였습니다. 

 

더보기

bool함수의 맨 마지막 return dCntr < radius + c.radius; 부분은 상수로 받은 원의 반지름과 변수로 받은 원의 반지름을 더한 값이 바로 윗줄에서 구한 두 원의 중심 간의 거리보다 큰지를 따지는 구문입니다. 이때 chkOverlap을 bool형 함수로 정의했으니 return이 돌려주어야 하는 값은 1(참: 원들의 반지름의 합이 중심 간의 거리보다 크다) 혹은 0(거짓: 원들의 반지름의 합이 중심 간의 거리보다 작다) 둘 중 하나가 될 것입니다. 

 

(추가) bool chkOverlap(const CircleClass& c) 구문의 의미에 대해서도 설명했습니다. 

 

더보기

직접 해보시면 알겠지만 이 함수에서 상수참조 대신 변수로 넘겨도 결괏값이 달라지지는 않습니다. 다만 지금처럼 상수참조를 하면, 만에 하나 함수 내에서 값을 변경하려고 시도하더라도 바뀌지 않습니다. 

① CircleClass 앞에 const를 붙인 이유: 매개변수로 사용할 객체를 상수로 쓰겠다는 뜻이고, 혹시라도 원본인 c2의 값이 바뀌지 않게 하기 위한 안전장치입니다.
② &를 붙인 이유: 값을 직접 복사하지 않고 참조 복사를 하기 위해서입니다. 또한 원래 &는 변수만 참조할 수 있지만, 위에서 이 변수를 상수로 불러왔기 때문에 상수 참조를 쓸 수 있습니다. 
③ 뒤에 붙는 const: 이 함수 내에서 멤버 변수에 대한 값을 변경하지 못하게 하는 장치입니다(변수 말고 상수로 쓰겠다는 표시).