본문 바로가기

C++ 프로그래밍 (1학년 2학기)

231116 C++ 프로그래밍 11주차

1.객체지향 언어의 3가지 특징

  • 캡슐화(encapsulation): 캡슐화는 데이터와 그 데이터를 처리하는 메서드를 하나의 단위로 묶는 것을 말합니다. 이를 통해 데이터의 접근을 제한하고, 데이터와 관련된 작업을 수행하는 메서드를 통해 데이터에 접근할 수 있도록 합니다. 예를 들어, C++에서 클래스(class)는 멤버 변수와 멤버 함수를 하나의 단위로 캡슐화할 수 있습니다.
class Circle {
private:
    double radius;
public:
    void setRadius(double r) {
        radius = r;
    }
    double getArea() {
        return 3.14 * radius * radius;
    }
};
  • 상속성(inheritance): 상속성은 기존에 정의된 클래스의 속성과 메서드를 다른 클래스에서 재사용할 수 있는 기능입니다. 기존의 클래스를 부모 클래스 또는 상위 클래스라고 하고, 이를 상속받는 클래스를 자식 클래스 또는 하위 클래스라고 합니다. 자식 클래스는 부모 클래스의 속성과 메서드를 그대로 물려받아 사용할 수 있으며, 필요에 따라 재정의(오버라이딩)하거나 새로운 속성과 메서드를 추가할 수 있습니다. 
class Shape {
protected:
    int width;
    int height;
public:
    void setWidth(int w) {
        width = w;
    }
    void setHeight(int h) {
        height = h;
    }
};

class Rectangle : public Shape {
public:
    int getArea() {
        return width * height;
    }
};
  • 다형성(polymorphism): 다형성은 같은 이름의 메서드가 다른 동작을 하는 것을 말합니다. 다형성을 통해 하나의 인터페이스를 가지고 다양한 객체를 처리할 수 있습니다. 이는 상속과 연결되어 부모 클래스 타입으로 자식 클래스의 객체를 다룰 수 있는 특징을 가지고 있습니다. 
class Animal {
public:
    virtual void makeSound() {
        cout << "동물이 소리를 낸다." << endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() {
        cout << "멍멍!" << endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() {
        cout << "야옹~" << endl;
    }
};

2. C++에서 polymorphism을 구현하는 방법

  • 부모 클래스(Base class) 선언: 다형성을 구현하기 위해 기본이 되는 부모 클래스를 선언합니다. 이 클래스는 가상 함수를 포함해야 합니다. 가상 함수는 virtual 키워드를 사용하여 선언됩니다.
class Animal {
public:
    virtual void makeSound() {
        cout << "동물이 소리를 낸다." << endl;
    }
};
  • 자식 클래스(Derived class) 정의: 부모 클래스를 상속받아 자식 클래스를 정의합니다. 자식 클래스에서는 부모 클래스의 가상 함수를 재정의(오버라이딩)합니다.
class Dog : public Animal {
public:
    void makeSound() {
        cout << "멍멍!" << endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() {
        cout << "야옹~" << endl;
    }
};
  • 다형성 활용: 부모 클래스의 포인터를 사용하여 다양한 자식 클래스의 객체를 다룹니다. 이때, 부모 클래스의 포인터를 사용하여 가상 함수를 호출하면, 실제로 실행되는 함수는 해당 객체의 타입에 맞는 함수가 호출됩니다. 이를 통해 다양한 객체를 동일한 인터페이스로 다룰 수 있습니다.
void processAnimal(Animal* animal) {
    animal->makeSound();
}

int main() {
    Animal* dog = new Dog();
    Animal* cat = new Cat();

    processAnimal(dog); // "멍멍!" 출력
    processAnimal(cat); // "야옹~" 출력

    delete dog;
    delete cat;

    return 0;
}

3. 다형성(polymorphism)의 종류

다형성(polymorphism)의 종류
C++에서 다형성(polymorphism)의 종류

4. 함수 중첩이란?

  • 하나의 함수명을 여러 개의 유사 목적으로 사용할 수 있다.

5.

#include <iostream>
int add(int i, int j)
{
	return (i + j);
}
//double add(int i, int j)
//{
//	return ((double)i + (double)j);
//} // 매개변수가 같기 때문에 이런 함수는 덧붙일 수 없다.
double add(double i, double j)
{
	return (i + j);
}
int main()
{
	std::cout << add(10, 20) << std::endl;
	std::cout << add(10.5, 20.3) << std::endl;
	return 0;
}

6.

#include <iostream>
template <class T> T Max(T i, T j)
{
	return i > j ? i : j;
} // 아래의 함수 선언은 이 코드로 대체 가능하다.
int Max(int i, int j)
{
	return i > j ? i : j;
}
double Max(double i, double j)
{
	return i > j ? i : j;
}
char Max(char i, char j)
{
	return i > j ? i : j;
}
int main()
{
	std::cout << Max(1, 2) << std::endl;
	std::cout << Max(7.5, 3.6) << std::endl;
	std::cout << Max('A', 'B');
	return 0;
}

7. 함수중첩을 하는 2가지 경우

  • 매개변수의 형이 다른 경우
  • 매개변수의 개수가 다른 경우

8. 

#include <iostream>
int add(int i, int j)
{
	return (i + j);
}
float add(float i, float j)
{
	return (i + j);
}
double add(double i, double j)
{
	return (i + j);
}
int add(int i, int j, int k)
{
	return (i + j + k);
}
int add(int i, int j, int k, int l)
{
	return (i + j + k + l);
}
int main()
{
	std::cout << add(1, 2) << std::endl;
	std::cout << add(1.1, 2.8) << std::endl;
	std::cout << add(1.4, 2.2) << std::endl;
	std::cout << add(1, 2, 3) << std::endl;
	std::cout << add(1, 2, 3, 4) << std::endl;
	return 0;
}

9. 

#include <iostream>
class Dog {
private:
	int age;
public:
	Dog() { age = 1; } // 매개변수가 없는 생성자, 자동 inline
	Dog(int a) { age = a; } // 매개변수가 하나인 생성자
	~Dog();
	int getAge();
	void setAge(int a);
};
Dog::~Dog(){	std::cout << "소멸";}
int Dog::getAge(){	return age;}
void Dog::setAge(int a){	age = a;}
int main()
{
	Dog happy(3), meri;
	std::cout << happy.getAge() << "," << meri.getAge();
	return 0;
}

10. 

11. 

#include <iostream>
class Dog {
private:
    int age;
public:
    Dog() { age = 1; } // 매개변수가 없는 생성자, 자동 inline
    Dog(int a) { age = a; } // 매개변수가 하나인 생성자
    ~Dog();
    int getAge();
    void setAge(int a);
};
Dog::~Dog(){    std::cout << "소멸";}
int Dog::getAge(){    return age;}
void Dog::setAge(int a){    age = a;}
int main()
{
    Dog happy(3), meri;
    std::cout << happy.getAge() << "," << meri.getAge();
    return 0;
}

12. 생성자 중첩 예(배열)

#include <iostream>
using std::cout;
using std::endl;
class Dog {
private:
	int age;
public:
	Dog() { age = 1; }
	// 매개변수가 없는 생성자
	Dog(int a) { age = a; }
	// 매개변수가 하나인 생성자
	~Dog();
	int getAge();
	void setAge(int a);
};
Dog::~Dog()
{
	std::cout << "소멸\n";
}
int Dog::getAge()
{
	return age;
}
void Dog::setAge(int a)
{
	age = a;
}
int main()
{
	Dog happy[5];
	Dog meri[5] = { 1,2,3,4,5 };
	for (int i = 0; i < 5; i++)
		std::cout << happy[i].getAge() <<
		"," << meri[i].getAge() << std::endl;
	return 0;
}

13. 디폴트 인자

  • 별도의 매개변수를 전달하지 않아도 기본적인 값을 전달하도록 함수 원형을 선언할 때 디폴트 값을 지정할 수 있다.
  • 디폴트 매개변수를 정의하기 시작하면 그 다음(오른쪽)의 매개변수들은 모두 디폴트 매개변수를 가져야 한다.
  • main()함수 전에 함수 선언을 하면 선언부에만 디폴트 인자를 지정해야 한다.
#include <iostream>
int add(int i=1, int j=2) // 형식매개변수 //int add(int i=1, int j); 라고 쓰면 오류남
{
	return(i + j);
}
int main()
{
	std::cout << add() << ","; // 실매개변수 없음, 3
	std::cout << add(10) << ","; // 실매개변수 한 개, 12
	std::cout << add(10, 20); // 실매개변수 두개, 30
	return 0;
}

14.

  • 디폴트 매개변수를 갖는 생성자이므로 생성자 중첩을 시키는 효과와 같다.
  • 디폴트 매개변수의 사용은 함수 중첩의 축약형인 것을 알 수 있다.
  • 즉, 다음과 같은 2개의 생성자가 있는 것과 같다. Dog() {age=1;} Dog(int a){age=a;}
  • 위 2개의 생성자를 넣으려면 디폴트함수를 쓰지 말아야 함
#include <iostream>
class Dog {
private:
	int age;
public:
	Dog(int a = 1) { age = a; }
	// 디폴트 매개변수를 갖는 생성자
	~Dog();
	int getAge();
	void setAge(int a);
};
Dog::~Dog()
{
	std::cout << "소멸\n";
}
int Dog::getAge()
{
	return age;
}
void Dog::setAge(int a)
{
	age = a;
}
int main()
{
	Dog meri, happy(5);
	std::cout << happy.getAge() << "," <<
		meri.getAge() << std::endl;
	return 0;
}

 

15.

#include <iostream>
class Dog {
private:
	int age;
public:
	Dog(int a = 1);
	// 디폴트 매개변수를 갖는 생성자
	~Dog();
	int getAge();
	void setAge(int a);
};
Dog::Dog(int a) { age = a; }
Dog::~Dog(){	std::cout << "소멸\n";}
int Dog::getAge(){	return age;}
void Dog::setAge(int a){ 	age = a;}
int main()
{
	Dog meri, happy(5);
	std::cout << happy.getAge() << "," <<
		meri.getAge() << std::endl;
	return 0;
}

 

참고 자료 : 한성현 교수님 수업자료

댓글