1학년 대학 수업/C++ 프로그래밍

9주차 복습 과제

hawon6691 2025. 10. 30. 16:29
728x90

1. 객체(Object)와 멤버(Member)

  • 객체(Object):
    클래스(Class)를 기반으로 생성된 실제 메모리에 존재하는 인스턴스.
    클래스는 설계도, 객체는 그 설계도로 만들어진 실제 물건이다.
  • class Person { public: int age; void speak() {} }; Person p1; // p1은 Person 클래스의 객체
  • 멤버(Member):
    클래스 내부에 선언된 변수(멤버 변수)와 함수(멤버 함수)를 말한다.
  • class Person { public: int age; // 멤버 변수 void speak(); // 멤버 함수 };

2. 생성자(Constructor)

  • 정의:
    객체가 생성될 때 자동으로 호출되는 특수한 멤버 함수.
    객체의 초기화를 담당한다.
  • 특징:
    • 클래스 이름과 동일하다.
    • 반환형이 없다(void도 없음).
    • 오버로딩 가능(여러 형태 정의 가능).
    • 객체 생성 시 한 번만 호출된다.
    class Person {
    public:
        int age;
        // 기본 생성자
        Person() {
            age = 0;
        }
    
        // 매개변수가 있는 생성자
        Person(int a) {
            age = a;
        }
    };
    
    Person p1;     // 기본 생성자 호출
    Person p2(20); // 매개변수 생성자 호출
    

3. 소멸자(Destructor)

  • 정의:
    객체의 생명주기가 끝날 때 자동으로 호출되는 특수한 멤버 함수.
    객체가 점유한 자원을 해제(동적 메모리 등)하는 역할을 한다.
  • 특징:
    • 클래스 이름 앞에 ~를 붙인다.
    • 반환형과 매개변수가 없다.
    • 한 클래스에 하나만 존재한다.
    • 객체가 소멸될 때 자동 호출된다.
    class Person {
    public:
        Person() {
            cout << "생성자 호출\n";
        }
        ~Person() {
            cout << "소멸자 호출\n";
        }
    };
    
    int main() {
        Person p; // 생성자 호출
    }             // main 종료 시 소멸자 자동 호출
    

4. this 포인터

  • 정의:
    객체 자신을 가리키는 숨겨진 포인터.
    멤버 함수 내부에서 자동으로 전달된다.
  • 특징:
    • 모든 멤버 함수는 this 포인터를 암묵적으로 가진다.
    • 정적 멤버 함수에서는 사용할 수 없다.
    • 주로 멤버 변수와 매개변수 이름이 같을 때 구분용으로 사용된다.
    class Person {
    private:
        int age;
    public:
        void setAge(int age) {
            this->age = age; // 매개변수 age와 멤버 변수 age 구분
        }
    };
    

요약:

객체 클래스의 실체 new, 선언 시 인스턴스 클래스 기반
멤버 객체의 구성요소 - 변수, 함수 클래스 내부에 정의
생성자 초기화 객체 생성 시 클래스명과 동일 반환형 없음
소멸자 자원 해제 객체 소멸 시 ~클래스명() 매개변수 없음
this 포인터 자기 객체 참조 멤버 함수 내부 this-> 정적 함수 사용 불가

구분 역할 호출 시점 형태 특징

 

#include <iostream>

class Dog
{
private:
    int _age;

public:
    int getAge()
    {
        return _age;
    }
    void setAge(int age)
    {
        _age = age;
    }
};

int main()
{
    Dog coco;
    coco.setAge(1);
    std::cout << "Coco's age: " << coco.getAge() << " year(s) old." << '\n';

    return 0;
}

이 소스코드를 java, javascript, python, c#, swift 로 나타내면


Java

public class Dog {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public static void main(String[] args) {
        Dog coco = new Dog();
        coco.setAge(1);
        System.out.println("Coco's age: " + coco.getAge() + " year(s) old.");
    }
}

JavaScript

class Dog {
    #age;

    getAge() {
        return this.#age;
    }

    setAge(age) {
        this.#age = age;
    }
}

const coco = new Dog();
coco.setAge(1);
console.log(`Coco's age: ${coco.getAge()} year(s) old.`);

C#

using System;

class Dog
{
    private int age;

    public int GetAge()
    {
        return age;
    }

    public void SetAge(int age)
    {
        this.age = age;
    }
}

class Program
{
    static void Main()
    {
        Dog coco = new Dog();
        coco.SetAge(1);
        Console.WriteLine($"Coco's age: {coco.GetAge()} year(s) old.");
    }
}

Python

class Dog:
    def __init__(self):
        self._age = 0

    def get_age(self):
        return self._age

    def set_age(self, age):
        self._age = age


coco = Dog()
coco.set_age(1)
print(f"Coco's age: {coco.get_age()} year(s) old.")

Swift

class Dog {
    private var age: Int = 0

    func getAge() -> Int {
        return age
    }

    func setAge(_ age: Int) {
        self.age = age
    }
}

let coco = Dog()
coco.setAge(1)
print("Coco's age: \(coco.getAge()) year(s) old.")

 

이렇게 구성할 수 있다.

 

생성자와 소멸자는 반환형이 없어야 한다.

 

생성자(Constructor)와 소멸자(Destructor)는 반환형이 없어야 한다.

이유:

  • 생성자는 객체가 만들어질 때 자동으로 호출되고,
    객체 자체를 초기화하기 위한 특수 함수다.
    → 반환값을 가지지 않는다.
  • 소멸자는 객체가 소멸될 때 자동으로 호출되고,
    자원 해제(clean-up)만 수행한다.
    → 역시 반환값이 없다.

예시:

class Dog {
public:
    Dog()          // 생성자 (반환형 없음)
    {
        std::cout << "Dog created\n";
    }

    ~Dog()         // 소멸자 (반환형 없음, ~로 시작)
    {
        std::cout << "Dog destroyed\n";
    }
};

※ 만약 반환형을 지정하면 일반 함수로 취급되어,
생성자나 소멸자로 인식되지 않는다.

 

모든 객체지향 언어는 생성자를 가지고 있으며, 객체를 생성할 때 초기화를 담당합니다.

하지만 C++은 다른 객체지향 언어와 달리 소멸자를 명시적으로 정의할 수 있습니다.

이는 C++이 Garbage Collector를 사용하지 않기 때문입니다.

Java, C#과 같은 언어들은 메모리 관리를 자동으로 수행하지만,

C++에서는 메모리 할당과 해제를 개발자가 직접 관리해야 합니다.

이를 위해 C++은 포인터를 사용하며, 동적 메모리 할당(new)과 해제(delete)를 수동으로 처리해야 합니다.

이처럼 메모리 관리가 수동으로 이루어지기 때문에 초보자가 익숙해지기 어렵고 실수할 가능성도 높습니다.

그러나 이러한 수동 관리 덕분에 메모리 사용과 성능 면에서 다른 언어보다 훨씬 효율적이며,

고성능 시스템이나 게임 개발 등에서 C++가 여전히 많이 사용되는 이유이기도 합니다.

 

요약하면 다음과 같다.


1. 모든 객체지향 언어는 생성자 개념을 가진다.

  • 객체가 생성될 때 초기화 작업을 수행한다.
  • C++, Java, C#, Python, Swift 모두 존재한다.

2. C++만 소멸자를 명시적으로 가진다.

  • 객체가 소멸될 때 호출되는 함수(~ClassName()).
  • 다른 언어들은 대부분 **GC(Garbage Collector)**가 자동으로 메모리를 해제한다.
    → 개발자가 소멸자를 직접 호출하거나 정의할 필요가 없다.

3. C++은 수동 메모리 관리

  • GC가 없기 때문에 개발자가 직접 new로 할당하고 delete로 해제해야 한다.
  • 이 때문에 **포인터(pointer)**가 필요하다.
Dog* pDog = new Dog(); // 동적 할당
pDog->setAge(2);
delete pDog;           // 수동 해제 (소멸자 호출됨)

4. **GC 언어(Java, C#, Python 등)**와의 비교

메모리 관리 수동 (new / delete) 자동 (GC가 해제)
소멸자 있음 (~ClassName()) 없음 (대신 finalize()나 __del__이 있지만 거의 안 씀)
포인터 있음 직접 사용 불가
성능 제어 세밀함 (직접 해제 가능) 단순하지만 제어권 낮음

구분 C++ Java / C# / Python


결론:
C++의 가장 큰 차이는 GC가 없다는 점이고, 그로 인해 포인터와 수동 메모리 관리가 필수적이다.
이 구조 덕분에 성능 제어는 세밀하지만, 관리 실수 시 메모리 누수나 오류가 발생하기 쉽다.

 

this 키워드는 객체지향 프로그래밍에서 매우 중요한 개념입니다. 언어별로 약간 차이가 있지만 기본 의미는 같습니다. 


1. 기본 개념

this는 **현재 객체 자신을 가리키는 참조(포인터)**입니다.
즉, 메서드나 생성자 안에서 this를 사용하면 지금 메서드를 호출한 객체 자신을 참조할 수 있습니다.


2. 사용 사례

(1) 멤버 변수와 매개변수 구분

class Dog {
private:
    int age;

public:
    void setAge(int age) {
        this->age = age; // 멤버 변수 age와 매개변수 age 구분
    }
};
  • 여기서 age는 매개변수와 멤버 변수 이름이 같아요.
  • this->age는 객체의 멤버 변수, age는 함수 매개변수를 의미합니다.

(2) 메서드 체이닝

class Dog {
private:
    int age;

public:
    Dog& setAge(int age) {
        this->age = age;
        return *this; // 객체 자신을 반환
    }
};

Dog dog;
dog.setAge(2).setAge(3); // 메서드 체이닝 가능
  • this를 반환하면 여러 메서드를 이어서 호출할 수 있습니다.

(3) 객체 자신 전달

class Dog {
public:
    void printMe(Dog* other) {
        std::cout << "I am this object: " << this << std::endl;
        std::cout << "Other object: " << other << std::endl;
    }
};
  • this를 다른 함수나 메서드에 전달할 수 있습니다.

(4) 생성자에서 다른 생성자 호출 (C++11 이상)

class Dog {
private:
    int age;
public:
    Dog() : Dog(1) {} // 다른 생성자 호출
    Dog(int a) : age(a) {}
};
  • C++에서는 this 대신 delegating constructor를 이용하지만, 다른 언어(Java, C#)에서는 this()를 사용합니다.

3. 요약

  • this = 현재 객체 자신
  • 주로 사용되는 경우:
    1. 멤버 변수와 매개변수 구분
    2. 메서드 체이닝
    3. 객체 자신 전달
    4. 생성자 내부 다른 생성자 호출 (언어별 차이)

C++, Java, C#에서 this 키워드의 사용법과 특징을 비교해서 정리하면 이렇게 볼 수 있습니다.

기본 의미 현재 객체를 가리키는 포인터 (this는 포인터) 현재 객체를 가리키는 참조 (this는 참조) 현재 객체를 가리키는 참조
멤버 변수 구분 this->멤버로 매개변수와 구분 this.멤버로 매개변수와 구분 this.멤버로 매개변수와 구분
메서드 체이닝 return *this; 후 체이닝 가능 return this; 후 체이닝 가능 return this; 후 체이닝 가능
생성자 호출 C++11 이상: Delegating Constructor 사용 (Dog() : Dog(1) {}) this()로 다른 생성자 호출 가능 this()로 다른 생성자 호출 가능
객체 전달 this를 포인터로 전달 this를 참조로 전달 this를 참조로 전달
참고 포인터이므로 -> 사용 참조이므로 . 사용 참조이므로 . 사용

항목 C++ Java C#

요약

  1. C++: this는 포인터. ->로 멤버 접근. 메모리 직접 관리 필요.
  2. Java, C#: this는 참조. .로 멤버 접근. Garbage Collector로 메모리 자동 관리.
  3. 모든 언어에서 주로 멤버 변수와 매개변수 구분, 메서드 체이닝, 생성자 호출, 객체 전달에 사용됨.

 

일반 객체가 멤버에 접근하기 위해 사용하는 연산자는 . 이고 직접 참조 연산자라고 한다.

포인터 객체가 멤버에 접근하기 위해 사용하는 연산자는 -> 이고 간접 참조 연산자라고 한다.

 

 

C 언어에서는 문자열을 다룰 때 strcpy, strcat 같은 함수를 사용해야 해서 코드가 복잡해지고,

버퍼 오버플로우 같은 위험도 있습니다.
반면 C++에서는 std::string을 사용하면 문자열 대입과 연결이 훨씬 간단해집니다. 예를 들어,

std::string a = "Hello";
std::string b = "World";
a += b;  // 문자열 결합

처럼 간단히 쓸 수 있습니다.

 

하지만 std::string의 단점도 있습니다.
std::string은 내부적으로 가변 크기 버퍼를 사용하기 때문에,

문자열의 길이가 증가할 때 자동으로 메모리를 재할당합니다.
일반적으로 크기가 부족해질 때마다 현재 용량의 2배로 늘리는데,

이 과정에서 기존 문자열을 새로운 메모리 공간으로 복사하는 작업이

일어나므로 성능 저하가 발생할 수 있습니다.

 

즉, 문자열이 자주 커지거나 매우 큰 데이터를 다루는 경우

std::string은 비효율적일 수 있습니다.
이럴 때는 성능을 위해 **고정 크기 배열(char 배열)**이나

std::vector<char> 같은 구조를 사용하는 것이 더 적절할 수 있습니다.

 

요약하자면,

  • std::string → 사용이 편리하고 안전하지만, 큰 데이터나 잦은 크기 변경에는 비효율적.
  • char 배열 → 관리가 복잡하지만, 메모리 제어와 성능 측면에서는 효율적.

일반 변수를 배열로 선언할 수 있듯이, 객체도 배열 형태로 선언할 수 있습니다.
즉, 동일한 클래스의 객체를 여러 개 만들고 싶을 때는 객체 배열을 사용하면 됩니다.

예를 들어,

class Dog {
public:
    void bark() {
        std::cout << "Woof!" << std::endl;
    }
};

int main() {
    Dog dogs[3];  // Dog 객체 3개를 배열로 선언
    dogs[0].bark();
    dogs[1].bark();
    dogs[2].bark();
}

위 코드처럼 Dog 클래스의 객체를 배열로 선언하면, 각각의 배열 요소가 독립적인 객체로 생성됩니다.
따라서 각 객체는 자신만의 멤버 변수와 메서드를 가지고 동작합니다.

다만, 생성자에 매개변수가 있는 경우에는 객체 배열을 초기화 리스트나 **동적 할당(new)**을 이용해야 합니다.

예시:

class Dog {
public:
    Dog(int age) { std::cout << "Dog age: " << age << std::endl; }
};

int main() {
    Dog dogs[3] = { Dog(1), Dog(2), Dog(3) }; // 초기화 리스트
}

요약하자면,

  • 객체도 배열 형태로 선언 가능하다.
  • 각 배열 요소는 독립적인 객체로 동작한다.
  • 생성자에 인자가 있을 경우 초기화 방식에 주의해야 한다.

생성자는 거의 모든 객체지향 언어에서 기본 개념으로, 객체가 생성될 때 자동으로 호출되어 초기화를 담당합니다.
한편, 대부분의 현대 객체지향 언어(Java, C#, Python 등)는 **Garbage Collector(GC)**가 내장되어 있어서, 사용이 끝난 객체의 메모리를 자동으로 해제합니다.
따라서 이러한 언어들에서는 별도의 **소멸자(destructor)**가 필요하지 않습니다.

하지만 C++은 Garbage Collector가 존재하지 않기 때문에, 개발자가 직접 메모리를 관리해야 합니다.
이때 객체가 소멸될 때 자동으로 호출되는 소멸자를 이용해, 동적으로 할당된 자원을 해제해야 합니다.

예를 들어,

class Dog {
public:
    Dog() { std::cout << "생성자 호출" << std::endl; }
    ~Dog() { std::cout << "소멸자 호출" << std::endl; }
};

int main() {
    Dog coco;  // 생성자 호출
}               // main 함수 끝나면 소멸자 자동 호출

이처럼 C++의 소멸자는 명시적으로 호출할 필요가 없으며, 객체의 생명 주기가 끝날 때 자동으로 실행됩니다.
즉, 개발자는 소멸자 안에서 동적 메모리 해제, 파일 닫기, 자원 정리 등을 처리하면 됩니다.


요약하자면,

  • 생성자는 객체의 초기화, 소멸자는 자원 해제 담당
  • 대부분의 언어는 GC가 있어서 소멸자가 필요 없음
  • C++은 GC가 없기 때문에 소멸자를 통해 자원을 직접 정리해야 함
  • 단, 소멸자 호출 자체는 자동으로 이루어짐
Dog() { name = "IX"; age = 0; weight = 0.0; } 
Dog() : name("IX"), age(0), weight(0.0) {} 
Dog() : name{"IX"}, age{0}, weight{0.0} {}


이 세 개의 생성자는 동작 결과는 같지만, 초기화 방식실행 시점, 효율성에서 차이가 있습니다.
하나씩 정확히 짚어볼게요.


🔹 1️⃣ 첫 번째: 일반 대입 방식

Dog() {
    name = "IX";
    age = 0;
    weight = 0.0;
}

🔸 특징

  • 생성자가 실행될 때 먼저 멤버 변수가 기본 생성으로 초기화된 뒤, 그 후에 대입(assignment) 이 이루어집니다.
  • 즉, 객체가 만들어지고 나서 값을 “넣는” 방식입니다.

🔸 동작 과정

  1. name, age, weight의 기본 생성자가 먼저 호출됨
  2. 그다음에 각각 "IX", 0, 0.0으로 대입(assign)

🔸 단점

  • 불필요한 기본 생성 + 대입 과정이 일어나므로 비효율적
  • 특히 std::string처럼 동적 메모리를 사용하는 타입에서는 임시 객체 생성 → 복사 → 해제가 발생

🔹 2️⃣ 두 번째: 멤버 이니셜라이저 리스트 (괄호 () 사용)

Dog() : name("IX"), age(0), weight(0.0) {}

🔸 특징

  • 멤버 변수를 생성할 때 동시에 초기화합니다.
  • 즉, 생성자 본문이 실행되기 전에 멤버가 이미 초기화됩니다.

🔸 장점

  • 불필요한 대입이 없고 한 번에 초기화
  • 성능이 좋고, 상수(const), 참조(&) 멤버도 이 방식으로만 초기화 가능

🔸 권장 사용

대부분의 경우 이 방식을 쓰는 것이 가장 효율적입니다.


🔹 3️⃣ 세 번째: 멤버 이니셜라이저 리스트 (중괄호 {} 사용)

Dog() : name{"IX"}, age{0}, weight{0.0} {}

🔸 특징

  • C++11 이후 등장한 통합(uniform) 초기화 방식입니다.
  • {}를 사용하면 복사 초기화, 직접 초기화, 리스트 초기화를 통합적으로 처리합니다.
  • narrowing(축소 변환) 오류를 컴파일 시점에 막을 수 있습니다.
  • int a{3.14}; // ❌ 오류 — 실수 → 정수 축소 변환 금지 int a = 3.14; // ⚠️ 가능하지만 값은 3으로 손실됨

🔸 장점

  • 타입 안정성이 높고, 실수로 인한 변환을 막을 수 있음
  • 현대 C++ 스타일로 추천됨

✅ 정리 비교표

① 본문 대입 생성 후 대입 name = "IX"; 🔻낮음 기본 생성 후 대입 ❌ 비효율
② 이니셜라이저( ) 생성 시점 name("IX") ✅높음 생성과 동시에 초기화 ✅ 권장
③ 이니셜라이저 { } 생성 시점 name{"IX"} ✅높음 타입 안정성 높음(C++11 이상) ✅ 적극 권장

구분 초기화 시점 구문 형태 성능 특징 권장 여부


💡결론

  • 기능적으로는 세 가지 모두 동일한 결과지만,
    • (1)은 비효율적 (추천 X)
    • (2)는 전통적이고 효율적 (C++03~)
    • (3)은 현대적이고 안전함 (C++11~)
  • 따라서 C++11 이후라면
    👉 Dog() : name{"IX"}, age{0}, weight{0.0} {}
    형태를 사용하는 것이 가장 좋습니다.

생성자로 넘겨주는 값을 작성해야 된다.

 

소멸자는 main 함수 끝에서 실행이 된다. 

자동으로 호출된다.

 

#include <iostream>

class Dog
{
private:
    int age;

public:
    Dog(int age) {this->age = age;}
    int getAge() { return age; }
    int setAge(int age) { this->age = age; }
    ~Dog() {}
};

int main() {
    Dog happy(1), coco(2);
    std::cout << happy.getAge() << '\n';
    std::cout << coco.getAge() << '\n';
    return 0;
}

 


1️⃣ Java

public class Dog {
    private int age;

    public Dog(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public static void main(String[] args) {
        Dog happy = new Dog(1);
        Dog coco = new Dog(2);

        System.out.println(happy.getAge());
        System.out.println(coco.getAge());
    }
}

2️⃣ Python

class Dog:
    def __init__(self, age):
        self.age = age

    def get_age(self):
        return self.age

    def set_age(self, age):
        self.age = age


happy = Dog(1)
coco = Dog(2)

print(happy.get_age())
print(coco.get_age())

3️⃣ JavaScript

class Dog {
    constructor(age) {
        this.age = age;
    }

    getAge() {
        return this.age;
    }

    setAge(age) {
        this.age = age;
    }
}

const happy = new Dog(1);
const coco = new Dog(2);

console.log(happy.getAge());
console.log(coco.getAge());

4️⃣ C#

using System;

class Dog
{
    private int age;

    public Dog(int age)
    {
        this.age = age;
    }

    public int GetAge()
    {
        return age;
    }

    public void SetAge(int age)
    {
        this.age = age;
    }

    static void Main()
    {
        Dog happy = new Dog(1);
        Dog coco = new Dog(2);

        Console.WriteLine(happy.GetAge());
        Console.WriteLine(coco.GetAge());
    }
}

5️⃣ Swift

class Dog {
    private var age: Int

    init(age: Int) {
        self.age = age
    }

    func getAge() -> Int {
        return age
    }

    func setAge(age: Int) {
        self.age = age
    }
}

let happy = Dog(age: 1)
let coco = Dog(age: 2)

print(happy.getAge())
print(coco.getAge())

💡 특징 비교

  • 모든 언어에서 **생성자(Constructor)**와 getter/setter는 동일한 역할.
  • Python과 JavaScript는 this 키워드 사용 방식이 다르지만, 의미는 동일.
  • C#과 Java는 C++과 가장 유사한 문법 구조.
  • Swift는 init이 생성자 역할을 하며, 메서드 호출 시 파라미터 이름 명시.

 


1️⃣ 클래스 정의: Cat

class Cat
{
private:
    std::string name;

public:
    Cat(std::string name) { this->name = name; }
    ~Cat() { std::cout << "bye~~\n"; }
    std::string getName() { return name; }
    void setName(std::string name) { this->name = name; }
};

🔹 멤버 변수

private:
    std::string name;
  • Cat 클래스 내부에서만 접근 가능한 비공개(private) 문자열 변수입니다.
  • 고양이의 이름을 저장하는 용도입니다.

🔹 생성자(Constructor)

Cat(std::string name) { this->name = name; }
  • Cat 객체가 생성될 때 호출됩니다.
  • 매개변수 name으로 받은 값을 **멤버 변수 name**에 저장합니다.
  • this->name은 현재 객체의 멤버 변수를 가리킵니다.

🔹 소멸자(Destructor)

~Cat() { std::cout << "bye~~\n"; }
  • 객체의 생명주기가 끝날 때 자동으로 호출됩니다.
  • 여기서는 "bye~~"를 출력하는 역할만 합니다.
  • C++에서는 동적 메모리 해제, 파일 닫기 등 자원 정리를 소멸자에서 처리할 수 있습니다.

🔹 Getter

std::string getName() { return name; }
  • 외부에서 멤버 변수 name의 값을 읽을 때 사용합니다.

🔹 Setter

void setName(std::string name) { this->name = name; }
  • 외부에서 멤버 변수 name의 값을 변경할 때 사용합니다.
  • 매개변수 name과 멤버 변수 name이 같기 때문에, this->name을 사용해서 멤버 변수를 명확히 구분합니다.

2️⃣ main 함수

int main()
{
    Cat coco("coco");            // 생성자 호출, 이름 초기화

    coco.setName("코코");         // 이름 변경
    std::cout << "고양이 이름: " << coco.getName() << '\n'; // 출력

    return 0;
}

🔹 실행 순서

  1. Cat coco("coco");
    • coco 객체 생성
    • 생성자 호출 → 이름 "coco"로 초기화
  2. coco.setName("코코");
    • 멤버 변수 name을 "코코"로 변경
  3. std::cout << coco.getName();
    • "코코" 출력
  4. main 종료 시 coco 객체 소멸
    • 소멸자 호출 → "bye~~" 출력

3️⃣ 실행 결과

고양이 이름: 코코
bye~~
  • 먼저 이름이 "코코"로 변경되어 출력되고,
  • 프로그램 종료 시 소멸자가 호출되어 "bye~~"가 출력됩니다.

💡 요약

  • 생성자: 객체 생성 시 초기화
  • 소멸자: 객체 소멸 시 정리 및 출력
  • getter/setter: private 멤버 변수 접근/수정
  • this: 현재 객체의 멤버를 가리킴

 

728x90

'1학년 대학 수업 > C++ 프로그래밍' 카테고리의 다른 글

10주차 복습 과제  (0) 2025.11.06
10주차 예습 과제  (0) 2025.11.05
9주차 예습 과제  (0) 2025.10.25
7주차 복습 과제  (0) 2025.10.16
7주차 중간고사 공지  (0) 2025.10.16