[C++] - 5일차(표준 입출력 & 상속)

Jun·2026년 2월 18일

c++

목록 보기
5/6

표준 입출력과 상속

1. 표준 입출력 및 문자열 결합

C++에서 cincout을 이용해 문자열을 입력받고 결합하는 기초 예제입니다.
string 클래스를 사용하기 위해서는 <string> 헤더를 포함해야 합니다.

이름과 성을 입력받아 결합하는 코드

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

    int main() {
        // 변수 선언
        string first;
        string last;
        string space = " ";
        string dot = ".";
        string fullName;

        // 입력
        cout << "이름을 입력 :"; // << endl;을 사용하지 않으면 같은 줄에서 입력
        cin >> last;
        cout << "성을 입력 :";
        cin >> first;

        fullName = first + space + dot + last;

        cout << "전체 이름 : " << fullName << endl;
    }

출력 결과 비교

  • endl 미사용 시 (기본)
    이름을 입력 : 길동
    성을 입력 : 홍

  • endl 사용 시 (줄바꿈 발생)
    이름을 입력 :
    길동
    성을 입력 :


2. 상속 (Inheritance)

상속이란 클래스가 다른 클래스에게 자신의 멤버(필드, 메서드)를 "물려주는 것"을 의미합니다.

용어 정리

  • 부모 클래스: 슈퍼 클래스(Super), 기본 클래스(Base)
  • 자식 클래스: 파생 클래스(Derived), 서브 클래스(Sub)

상속의 특징과 장점

  • 상속이 이루어지면 부모의 기능을 포함한 새로운 클래스가 만들어집니다.
  • 클래스의 간결성: 공통된 코드를 부모 클래스에 집중시켜 코드 중복을 줄입니다.
  • 자식 클래스에는 자신만의 멤버가 존재할 수 있으며, 부모에게 물려받은 멤버도 사용 가능합니다.

접근 제어 지시자와 상속

접근 제어 지시자클래스 외부 접근자식 클래스 접근클래스 내부 접근
public가능가능가능
protected불가능가능가능
private불가능불가능가능

상속 할 때 부모 클래스이 접근 제어지시자를
protected, private로 선언할 수 있다. (public만 되는게 아님)

  • ex) class Derived : protected Base
  • ex) class Derived : private Base

주의: 부모 클래스의 private 멤버는 자식 클래스에게 상속은 되지만, 자식 클래스에서 직접 접근할 수는 없습니다.


3. 상속 사용법 및 예제

기본 문법

	class 자식클래스 : 접근제어지시자 부모클래스 {
        // 추가 멤버
    };

상속 관계도

예제: Base와 Derived 클래스

	//부모 클래스
    class Base {
    public:
        void bFunc() {
            cout << "부모 클래스의 메서드" << endl;
        }
        int bNum;
    };

	//자식 클래스
    class Derived : public Base {
    public:
        void dFunc() {
            cout << "자식 클래스의 메서드" << endl;
        }
        int dNum;
    };

    int main() {
        Base b; //객체 생성
        Derived d; //객체 생성

        b.bFunc();
        b.bNum = 1;

        d.bFunc(); // 부모에게 물려받은 메서드 사용
        d.bNum = 2;
        d.dFunc();
        d.dNum = 1;
    }

4. 생성자 호출 순서

상속 관계에서 자식 클래스의 객체가 생성될 때, 반드시 부모 클래스의 생성자가 먼저 호출된 후 자식 클래스의 생성자가 호출됩니다.

    int main() {
        Derived d; // 1. 부모 생성자 호출 -> 2. 자식 생성자 호출
    }

5. 실전 상속 예시 (Animal 클래스)


    #include <iostream>
    using namespace std;

    class Animal {
    public:
        void breathe() {
            cout << "숨을 쉰다." << endl;
        }
        int age;
    };

    class Dog : public Animal {
    public:
        void walk() {
            cout << "걷는다." << endl;
        }
    };

    class Sparrow : public Animal {
    public:
        void fly() {
            cout << "난다." << endl;
        }
    };

    int main() {
        Dog d;
        d.age = 7;
        d.breathe(); // 부모 기능
        d.walk();    // 자식 기능
        
        Sparrow s;
        s.age = 1;
        s.breathe(); // 부모 기능
        s.fly();     // 자식 기능
    }

6. 업캐스팅 (Upcasting)

자식 클래스의 객체를 부모 클래스의 포인터(또는 참조)로 가리키는 것을 의미합니다.

    int main() {
        Dog d;
        Sparrow s;

        // 업캐스팅: 자식 주소를 부모 포인터에 대입
        Animal* p1 = &d; 
        Animal* p2 = &s;

        p1->breathe(); // 가능
        p2->breathe(); // 가능

        // p1->walk(); // 에러! 부모 포인터로는 자식 전용 멤버가 보이지 않음
    }

업캐스팅을 사용하는 이유 (장점)

  • "자식 기능을 못 쓰는데 왜 굳이 부모 포인터로 쓰나요?"라는 의문이 생길 수 있습니다.
    가장 큰 이유는 관리의 편의성 때문입니다.

    • 개별 관리의 불편함: 강아지 10마리, 참새 10마리를 관리하려면
      Dog dogList[10], Sparrow sparrowList[10]처럼 따로따로 리스트를 만들어야 합니다.

    • 통합 관리의 편리함: Animal* zoo[20] 하나만 만들면, 그 안에 강아지든 참새든 사자든 '동물'이라는 이름으로 한꺼번에 담을 수 있습니다.

Tip: 만약 부모 포인터 상태에서도 자식의 특정한 행동(예: 멍멍, 짹짹)을 하고 싶다면, 나중에 배울 '가상 함수(virtual function)''오버라이딩'을 사용하면 됩니다.

profile
Hard Trying

0개의 댓글