카테고리 없음

202208026이종윤 c프로그래밍 11주차 과제

jong133 2024. 11. 12. 13:46

함수중첩을 지원하는 프로그래밍언어들
뤼튼에게 물어보았다.

객체지향언어의 특징을 잘 이해할수있는 c++소스를 만들어서 설명해줘

답변


빠른 검색

C++에서 객체지향 프로그래밍의 특징을 잘 보여주는 예제를 만들어 보겠습니다. 이 예제는 캡슐화, 상속, 다형성, 추상화의 네 가지 특징을 포함합니다.

예제: 도형 클래스
cpp


#include <iostream>
#include <vector>
#include <memory>

using namespace std;

// 추상 클래스 (Abstraction)
class Shape {
public:
    virtual void draw() = 0; // 순수 가상 함수 (pure virtual function)
    virtual ~Shape() {} // 가상 소멸자 (virtual destructor)
};

// 캡슐화 (Encapsulation)
class Circle : public Shape {
private:
    double radius; // 원의 반지름

public:
    Circle(double r) : radius(r) {} // 생성자

    void draw() override { // 다형성 (Polymorphism)
        cout << "Drawing a Circle with radius: " << radius << endl;
    }
};

// 상속 (Inheritance)
class Rectangle : public Shape {
private:
    double width, height; // 직사각형의 너비와 높이

public:
    Rectangle(double w, double h) : width(w), height(h) {} // 생성자

    void draw() override { // 다형성 (Polymorphism)
        cout << "Drawing a Rectangle with width: " << width << " and height: " << height << endl;
    }
};

int main() {
    vector<unique_ptr<Shape>> shapes; // Shape 객체를 저장할 벡터

    // 객체 생성 및 저장
    shapes.push_back(make_unique<Circle>(5.0));
    shapes.push_back(make_unique<Rectangle>(4.0, 6.0));

    // 각 도형 그리기
    for (const auto& shape : shapes) {
        shape->draw(); // 다형성을 통해 각 도형의 draw() 호출
    }

    return 0;
}
코드 설명
추상화 (Abstraction):

Shape 클래스는 추상 클래스입니다. 이 클래스는 draw라는 순수 가상 함수(pure virtual function)를 가지고 있어, 실제 도형 클래스에서 반드시 구현해야 합니다.
캡슐화 (Encapsulation):

Circle 클래스와 Rectangle 클래스는 각각의 속성(radius, width, height)을 private으로 설정하여, 외부에서 직접 접근할 수 없도록 하고 있습니다. 각 클래스는 생성자를 통해 속성을 초기화합니다.
상속 (Inheritance):

Circle과 Rectangle 클래스는 Shape 클래스를 상속받습니다. 이를 통해 두 클래스는 Shape의 인터페이스를 구현하고, 공통된 기능을 공유할 수 있습니다.
다형성 (Polymorphism):

Shape 포인터를 사용하여 다양한 도형을 다룰 수 있습니다. shapes 벡터에 Circle과 Rectangle 객체를 저장하고, draw 메서드를 호출할 때 각 객체의 실제 타입에 따라 적절한 메서드가 호출됩니다. 이는 런타임에 결정되므로 다형성을 나타냅니다.
이 예제를 통해 C++에서 객체지향 언어의 특징을 잘 이해할 수 있습니다. 

자동형변환하는것을 코어션이라고한다. 이 코어션으로 1+2.5도 계산이 된다,

출처:https://www.youtube.com/channel/UCM8wseo6DkA-D7yGlCrcrwA

 

Smile Han

 

www.youtube.com

c++에서 대게일반적으로 3개의 다형성을 제공한다. c++에서 제공하는 다형성

출처:https://www.youtube.com/channel/UCM8wseo6DkA-D7yGlCrcrwA

 

Smile Han

 

www.youtube.com

 

()은 함수를 호출할때 인자를 전달하기위한 괄호이다.
함수 오버로딩은 기능이 비슷하면 같이 주는함수여서 int든 double이든 add를 쓰면 알아서 계산정리가 된다.
1번째 add함수와 3번째 add함수가 충돌이난다.그래서 3번째 add를 add2로 지정하면 해결된다.

출처:https://www.youtube.com/channel/UCM8wseo6DkA-D7yGlCrcrwA

 

Smile Han

 

www.youtube.com

 

그리고 함수를 보기좋게 접을려면 ctrl+m+o 다시펼칠려면 ctrl+m+l
계산만 된다면 같은함수의 이름으로 지정할수있다.
함수 오버로딩
함수중첩을 하는 2가지 경우

출처:https://www.youtube.com/channel/UCM8wseo6DkA-D7yGlCrcrwA

멤버변수만들기 2단계
3단계 게터 세터 만들기
게터에 인테자를 붙이고 리턴 에이지를 쓴다
세터에다가도 보이드를 붙이고 이번엔 age = a;를 쓴다
게터세터를 이용해서 감춰줘있던 값을 불러오기도한다. 즉 들어오는문 나가는문

생성자는 클래스의 도구와 같다. // Dog()=생성자

문제가 생겼다. 강아지는 1살부터니까 dog()생성자=클래스도구를 사용한다.

생성자 소멸자를 만들어보았다.
Dog소속이므로 Dog::를 붙혀준다.
그리고 깔끔하게 위에 퍼블릭밑에 함수들의 뒷함수를 생략하고;를 붙히면 잘 작동된다.
배열로 여러가지 똑같은 함수를 만들수있다. 초기값이있으면 매개변수가 있는예를 호출하고 초기값이없으면 매개변수 없는 생성자(inline)을 호출한다.

출처:https://www.youtube.com/channel/UCM8wseo6DkA-D7yGlCrcrwA

 

Smile Han

 

www.youtube.com

argument=인자 뤼튼에게 질문해봤다.
디폴트매개변수에다가 값을 쓰면 에러가 없어진다. =옆에 값을쓰면 디폴트인자를 쓰는것이다.

함수를 선언과 정의를 따로했을땐 선언부에다만 디폴트값을주고 정의부에는 따로 안준다.

디폴트인자를 갖는 생성자

함수중첩중에 가장 많이쓰는것은 생성자 중첩이다. 

디폴트인자를 쓸때조심해야되는것은선언부정의부에서 선언부에 디폴트값을 쓰면 무조건 정의부에도써야된다.

앞에 age에다가는 this->를 써서 구분을 한다.
name을위해서 게터세터를 다만들었다. name name 똑같기때문에 앞에 this->를 붙힌다.
중첩을 넣어 age와 name에 a를넣다.
디폴트인자를 갖는 생성자
멤버변수를 const로 지정하는게 좋다. 반드시해야되는건아니다.
함수의 선언을 밖으로 뺀거다.
주어진 C++ 코드는 Dog 클래스를 정의하고, 이 클래스를 사용하여 개체를 생성 및 조작하는 예제입니다. 각 부분에 대해 주석을 추가하고 설명하겠습니다. cpp #include <stdio.h> // 표준 입력 출력 라이브러리 (하지만 사용되지 않음) #include <iostream> // C++의 입력 출력 스트림 라이브러리 class Dog { private: int age; // 개의 나이를 저장하는 변수 std::string name; // 개의 이름을 저장하는 변수 public: // 기본 생성자 (주석 처리됨) // Dog() { // age = 1; // 기본 나이를 1로 설정 // name = "강아지"; // 기본 이름을 "강아지"로 설정 // } // 매개변수가 있는 생성자, 기본값 설정 Dog(int age = 1, std::string name = "강아지"); // 나이를 반환하는 메서드 int getAge() const; // 나이를 설정하는 메서드 void setAge(int age); // 이름을 반환하는 메서드 std::string getName() const; // 이름을 설정하는 메서드 void setName(std::string name); }; // 생성자 정의 Dog::Dog(int age, std::string name) { this->age = age; // 전달된 age를 클래스의 age에 저장 this->name = name; // 전달된 name을 클래스의 name에 저장 } // 나이를 반환하는 메서드 정의 int Dog::getAge() const { return age; } // 나이를 설정하는 메서드 정의 void Dog::setAge(int age) { this->age = age; } // 이름을 반환하는 메서드 정의 std::string Dog::getName() const { return name; } // 이름을 설정하는 메서드 정의 void Dog::setName(std::string name) { this->name = name; } int main() { Dog coco; // 기본 생성자를 사용하여 coco 객체 생성 Dog happy(3, "해피"); // 매개변수가 있는 생성자를 사용하여 happy 객체 생성 // coco의 이름과 나이를 출력 std::cout << coco.getName() << coco.getAge() << std::endl; // 결과: 강아지1 // happy의 이름과 나이를 출력 std::cout << happy.getName() << happy.getAge() << std::endl; // 결과: 해피3 // coco의 이름과 나이를 설정 coco.setName("코코"); coco.setAge(3); // 변경된 coco의 이름과 나이를 출력 std::cout << coco.getName() << coco.getAge() << std::endl; // 결과: 코코3 return 0; // 프로그램 종료 } 설명 클래스 선언: Dog 클래스는 개의 나이와 이름을 나타내는 두 개의 private 변수를 가지고 있습니다. 생성자: 기본 생성자(주석 처리됨)를 사용하면 age와 name의 기본값을 설정할 수 있습니다. 매개변수가 있는 생성자는 기본값을 제공하여 인자를 생략할 수 있습니다. 메서드: getAge, setAge, getName, setName 메서드를 통해 나이와 이름을 읽고 수정할 수 있습니다. main 함수: coco 객체를 기본 생성자로 생성하고, happy 객체를 매개변수를 사용하여 생성합니다. 각 객체의 이름과 나이를 출력하고, coco의 이름과 나이를 변경한 후 다시 출력합니다. 이 코드는 객체지향 프로그래밍의 기본적인 개념인 캡슐화와 생성자 활용을 잘 보여줍니다.