C++

11주차 강의 내용

wlsn 2024. 11. 12. 13:44

함수 오버로딩(Function Overloading)을 지원하는 프로그래밍 언어와 각각의 예제

 

C++

#include <iostream>
using namespace std;

class Example {
public:
    void display(int a) {
        cout << "정수: " << a << endl;
    }

    void display(double b) {
        cout << "실수: " << b << endl;
    }
};

int main() {
    Example obj;
    obj.display(10);      // 정수 호출
    obj.display(3.14);    // 실수 호출
    return 0;
}

 

JAVA

class Example {
    void display(int a) {
        System.out.println("정수: " + a);
    }

    void display(double b) {
        System.out.println("실수: " + b);
    }
}

public class Main {
    public static void main(String[] args) {
        Example obj = new Example();
        obj.display(10);      // 정수 호출
        obj.display(3.14);    // 실수 호출
    }
}

 

C#

using System;

class Example {
    public void Display(int a) {
        Console.WriteLine("정수: " + a);
    }

    public void Display(double b) {
        Console.WriteLine("실수: " + b);
    }
}

class Program {
    static void Main() {
        Example obj = new Example();
        obj.Display(10);      // 정수 호출
        obj.Display(3.14);    // 실수 호출
    }
}

 

Swift

class Example {
    func display(a: Int) {
        print("정수: \(a)")
    }

    func display(b: Double) {
        print("실수: \(b)")
    }
}

let obj = Example()
obj.display(a: 10)      // 정수 호출
obj.display(b: 3.14)    // 실수 호출

 

Kotlin

class Example {
    fun display(a: Int) {
        println("정수: $a")
    }

    fun display(b: Double) {
        println("실수: $b")
    }
}

fun main() {
    val obj = Example()
    obj.display(10)       // 정수 호출
    obj.display(3.14)     // 실수 호출
}

 

캡슐화(Encapsulation):

데이터(속성)와 메서드(동작)를 하나의 단위인 객체로 묶는 것입니다. 이를 통해 객체의 내부 상태를 보호하고, 외부에서 직접 접근하지 못하도록 제한합니다. 객체의 내부 구현은 숨겨지고, 공개된 인터페이스(메서드)를 통해 상호작용합니다.


상속(Inheritance):

기존 클래스(부모 클래스)의 속성과 메서드를 새로운 클래스(자식 클래스)가 물려받는 기능입니다. 이를 통해 코드의 재사용성을 높이고, 공통된 기능을 부모 클래스에 정의하여 자식 클래스에서 쉽게 사용할 수 있습니다.


다형성(Polymorphism):

동일한 이름의 메서드가 서로 다른 클래스에서 다르게 동작하도록 하는 기능입니다. 주로 가상 함수와 오버로딩을 통해 구현됩니다. 이를 통해 코드의 유연성을 높이고, 다양한 객체를 동일한 방식으로 처리할 수 있습니다.


추상화(Abstraction):

복잡한 시스템을 단순화하여 중요한 부분만을 모델링하는 과정입니다. 객체의 중요한 속성과 동작만을 공개하고, 불필요한 세부사항은 숨깁니다. 인터페이스나 추상 클래스를 통해 구현할 수 있습니다.

 

코어션 : 자료형이 다른 계산을 할 때 자동으로 형변환이 되는 것

템플릿 (Generic function) : < >를 쓰고 C++, Java, C# 등에서 제네릭 타입을 정의할 때 사용

 

이렇게 int형,float형으로 나눠져있는 코드를 컴파일러가 솎아내 이름이 똑같더라도 자료형에 따라 자동적으로 불러옴.

 

#include <iostream>
int add(int i, int j)
{
	return (i + j);
}
double add(double i, double j)
{
	return (i + j);
}
double add(int i, int j)
{
	return ((double)i + (double)j);
}
int main()
{
	std::cout << add(10, 20) << std::endl;
	std::cout << add(10.5, 20.3) << std::endl;
	return 0;
}

위 코드와 같이 자료형은 같고 리턴형만 다른 경우 오버로드가 되지 않는다.

리턴이 되게 하려고 한다면 자료형이 다르거나 개수가 달라야한다.

 

#include <iostream>
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;
}

이 소스를 다르게 변환시킬 수 있다.

#include <iostream>
template<class T>
T Max(T i, T 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;
}

template을 쓴 결과다.

 

이름이 같더라도 함수중첩을 할 수 있게 하려면 자료형이 다르거나, 매개변수의 개수가 달라야한다.

 

#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.3f, 2.6f) << std::endl;
	std::cout << add(6.5, 3.8) << std::endl;
	std::cout << add(1, 2, 3) << std::endl;
	std::cout << add(1, 2, 3, 4) << std::endl;

	return 0;
}

 

이렇게 이름이 같더라도 자료형이 다르거나 개수가 다르다면 모두 자동형변환이 되어 출력이 가능하다.

 

1단계

#include <iostream>
class Dog {

};
int main()
{
	return 0;
}

 

2단계

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
};
int main()
{
	return 0;
}

 

3단계

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
public:
	getAge() { //getAge, setAge 만들기

	}
	setAge() {

	}
};
int main()
{
	return 0;
}

 

4단계

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
public:
	int getAge() { //getAge, setAge 만들기
		return age; // int, return age; 만들기
	}
	setAge() {

	}
};
int main()
{
	return 0;
}

 

5단계

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
public:
	int getAge() { //getAge, setAge 만들기
		return age; // int, return age; 만들기
	}
	void setAge(int a) { //void, int a선언 후 age = a; 만들기
		age = a;
	}
};
int main()
{
	return 0;
}

 

6단계

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
public:
	int getAge() { //getAge, setAge 만들기
		return age; // int, return age; 만들기
	}
	void setAge(int a) { //void, int a선언 후 age = a; 만들기
		age = a;
	}
};
int main()
{
	Dog coco;
	std::cout << coco.getAge(); // coco.getAge 만들기

	return 0;
}

입력 함수가 없기때문에 쓰레기 값 출력

 

7단계

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
public:
	int getAge() { //getAge, setAge 만들기
		return age; // int, return age; 만들기
	}
	void setAge(int a) { //void, int a선언 후 age = a; 만들기
		age = a;
	}
};
int main()
{
	Dog coco;
	coco.setAge(3); // 나이 지정하기
	std::cout << coco.getAge(); // coco.getAge 만들기

	return 0;
}

 

8단계

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
public:
	Dog() { //생성자는 class 이름과 똑같다.

	}
	int getAge() { //getAge, setAge 만들기
		return age; // int, return age; 만들기
	}
	void setAge(int a) { //void, int a선언 후 age = a; 만들기
		age = a;
	}
};
int main()
{
	Dog coco;
	coco.setAge(3); // 나이 지정하기
	std::cout << coco.getAge(); // coco.getAge 만들기

	return 0;
}

생성자는 class 이름과 똑같다

 

9단계

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
public:
	Dog() { //생성자는 class 이름과 똑같다.
		age = 1;
	}
	int getAge() { //getAge, setAge 만들기
		return age; // int, return age; 만들기
	}
	void setAge(int a) { //void, int a선언 후 age = a; 만들기
		age = a;
	}
};
int main()
{
	Dog coco;
//	coco.setAge(3); // 나이 지정하기
	std::cout << coco.getAge(); // coco.getAge 만들기

	return 0;
}

이렇게 coco.setAge를 주석처리한다고 하더라도 쓰레기 값이 아닌 1이 출력되게 된다.

 

생성자 함수는 특이하게 return값이 없어도 void를 쓰지않는다.

 

10단계

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
public:
	Dog() { //생성자는 class 이름과 똑같다.
		age = 1;
	}
	Dog(int a) {
		age = a; //생성자를 2개만들고 기능을 살짝 변경해서 만들기
	}
	int getAge() { //getAge, setAge 만들기
		return age; // int, return age; 만들기
	}
	void setAge(int a) { //void, int a선언 후 age = a; 만들기
		age = a;
	}
};
int main()
{
	Dog coco,happy(5);
//	coco.setAge(3); // 나이 지정하기
	std::cout << coco.getAge() << std::endl; // coco.getAge 만들기
	std::cout << happy.getAge() << std::endl; // happy의 나이 출력하기
	return 0;
}

 

11단계

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
public:
	Dog() { //생성자는 class 이름과 똑같다.
		age = 1;
	}
	Dog(int a) {
		age = a; //생성자를 2개만들고 기능을 살짝 변경해서 만들기
	}
	~Dog() { //소멸자 함수는 생성자와 구분하기위해 "~"를 앞에 붙여준다.
		std::cout << "bye!\n";
	}
	int getAge() { //getAge, setAge 만들기
		return age; // int, return age; 만들기
	}
	void setAge(int a) { //void, int a선언 후 age = a; 만들기
		age = a;
	}
};
int main()
{
	Dog coco,happy(5);
//	coco.setAge(3); // 나이 지정하기
	std::cout << coco.getAge() << std::endl; // coco.getAge 만들기
	std::cout << happy.getAge() << std::endl; // happy의 나이 출력하기
	return 0;
}

 

12단계

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
public:
	Dog() { //생성자는 class 이름과 똑같다.
		age = 1;
	}
	Dog(int a) {
		age = a; //생성자를 2개만들고 기능을 살짝 변경해서 만들기
	}
	~Dog() { //소멸자 함수는 생성자와 구분하기위해 "~"를 앞에 붙여준다.
		std::cout << "bye!\n";
	}
	int getAge() { //getAge, setAge 만들기
		return age; // int, return age; 만들기
	}
	void setAge(int a) { //void, int a선언 후 age = a; 만들기
		age = a;
	}
};
Dog::Dog() { age = 1; }
Dog::Dog(int a) { age = a; }
Dog::~Dog() { std::cout << "bye!\n"; }
int Dog::getAge() { return age; }
void Dog::setAge(int a) { age = a; }

int main()
{
	Dog coco, happy(5);
	//	coco.setAge(3); // 나이 지정하기
	std::cout << coco.getAge() << std::endl; // coco.getAge 만들기
	std::cout << happy.getAge() << std::endl; // happy의 나이 출력하기
	return 0;
}

 

 

Default parameter에 대해 프로그래밍 언어별로 알려달라고 했을때의 결과값이다.

 

#include <iostream>
int add(int i = 1, int j = 2) // 형식매개변수
{
	return(i + j);
}
int main()
{
	std::cout << add() << ","; // 실매개변수 없음, 3
	std::cout << add(10) << ","; // 실매개변수 한 개, 12
	std::cout << add(10, 20); // 실매개변수 두개, 30
	return 0;
}

형식매개변수 옆에 값을 준다면 디폴트 매개변수가 된다.

실매개변수가 없더라도 리턴값을 반환할 수 있게 된다.

 

#include <iostream>
int add(int i = 1, int j = 2) // 형식매개변수
{
	return(i + j);
}
int main()
{
	std::cout << add() << ","; // 실매개변수 없음, 3
	std::cout << add(10) << ","; // 실매개변수 한 개, 12
	std::cout << add(10, 20); // 실매개변수 두개, 30
	return 0;
}
int add(int i, int j) {
	return(i + j);
}

만약 위 소스에서 int main부분 아래 int add에서 int i = 1, int j = 2라고 수정 했을 때 오류가 나 실행이 되지 않는다. 정의부에는 작성하면 안되기 때문이다.

 

#include <iostream>
class Dog {
private:
	int age;//멤버변수 추가
public:
	Dog(int a = 1);
//	Dog();
//	Dog(int a);
	~Dog();
	int getAge();
	void setAge(int a);
};
Dog::Dog(int a) { age = a; }
//Dog::Dog() { age = 1; }
//Dog::Dog(int a) { age = a; }
Dog::~Dog() { std::cout << "bye!\n"; }
int Dog::getAge() { return age; }
void Dog::setAge(int a) { age = a; }

int main()
{
	Dog coco, happy(5);
	//	coco.setAge(3); // 나이 지정하기
	std::cout << coco.getAge() << std::endl; // coco.getAge 만들기
	std::cout << happy.getAge() << std::endl; // happy의 나이 출력하기
	return 0;
}

새롭게 디폴트 매개변수를 선언한 코드다.

 

 

이름까지 저장할 수 있는 클래스

 

1단계

#include <iostream>
class Dog {
private:
	int age;
	std::string name;
public:
	int getAge() { return age; }
	void setAge(int a) { age = a; }
};
int main()
{
	return 0;
}

 

2단계

#include <iostream>
class Dog {
private:
	int age;
	std::string name;
public:
	int getAge() { return age; }
	void setAge(int age) {this -> age = age; }
};
int main()
{
	return 0;
}

age = a를 this -> age = age;로 변경

 

3단계

#include <iostream>
class Dog {
private:
	int age;
	std::string name;
public:
	int getAge() { return age; }
	void setAge(int age) {this -> age = age; }
	std::string getname() { return name; }
	void setname(std::string name) { this -> name = name; }
};
int main()
{
	return 0;
}

 

4단계

#include <iostream>
class Dog {
private:
	int age;
	std::string name;
public:
	int getAge() { return age; }
	void setAge(int age) {this -> age = age; }
	std::string getName() { return name; }
	void setName(std::string name) { this -> name = name; }
};
int main()
{
	Dog coco;
	coco.setName("코코");
	coco.setAge(1);
	std::cout << coco.getName() << coco.getAge();
	return 0;
}

인스턴스를 만들어 나이와 이름을 입력해 출력해보는 결과

 

5단계

#include <iostream>
class Dog {
private:
	int age;
	std::string name;
public:
	Dog() { age = 1; name = "강아지"; }
	int getAge() { return age; }
	void setAge(int age) {this -> age = age; }
	std::string getName() { return name; }
	void setName(std::string name) { this -> name = name; }
};
int main()
{
	Dog coco,happy;
	std::cout << coco.getName() << coco.getAge() << std::endl;
	std::cout << happy.getName() << happy.getAge() << std::endl;
	coco.setName("코코");
	coco.setAge(1);
	happy.setName("해피");
	happy.setAge(2);
	std::cout << coco.getName() << coco.getAge() << std::endl;
	std::cout << happy.getName() << happy.getAge() << std::endl;
	return 0;
}

처음은 초기값이 없으니 디폴트값인 강아지, 1이 연속적으로 출력되어 강아지1 강아지1이 나오게 된다.

 

6단계

#include <iostream>
class Dog {
private:
	int age;
	std::string name;
public:
	Dog() { age = 1; name = "강아지"; }
	Dog(int a, std::string n) { age = a; name = n; }
	int getAge() { return age; }
	void setAge(int age) {this -> age = age; }
	std::string getName() { return name; }
	void setName(std::string name) { this -> name = name; }
};
int main()
{
	Dog coco,happy(3, "해피");
	std::cout << coco.getName() << coco.getAge() << std::endl;
	std::cout << happy.getName() << happy.getAge() << std::endl;
	coco.setName("코코");
	coco.setAge(1);
	happy.setName("해피");
	happy.setAge(2);
	std::cout << coco.getName() << coco.getAge() << std::endl;
	std::cout << happy.getName() << happy.getAge() << std::endl;
	return 0;
}

생성자를 하나 더 추가해 해피의 이름과 나이를 바로 출력하게 할 수 있다.

 

7단계

#include <iostream>
class Dog {
private:
	int age;
	std::string name;
public:
//	Dog() { age = 1; name = "강아지"; }
	Dog(int a=1, std::string n="강아지") { age = a; name = n; }
	int getAge() { return age; }
	void setAge(int age) {this -> age = age; }
	std::string getName() { return name; }
	void setName(std::string name) { this -> name = name; }
};
int main()
{
	Dog coco,happy(3, "해피");
	std::cout << coco.getName() << coco.getAge() << std::endl;
	std::cout << happy.getName() << happy.getAge() << std::endl;
	coco.setName("코코");
	coco.setAge(1);
	happy.setName("해피");
	happy.setAge(2);
	std::cout << coco.getName() << coco.getAge() << std::endl;
	std::cout << happy.getName() << happy.getAge() << std::endl;
	return 0;
}

public에 첫줄을 주석처리한다고해도 int a를 int a = 1, std::string n을 std::string n="강아지"로 바꿀 수 있다.

 

	Dog(int age=1, std::string name="강아지") { this -> age = age; this -> name = name; }

int a를 int age로 바꾸고 std::string n을 std::string name으로 바꾸고 this를 추가해주는게 더 좋다.

 

std::string getName() const { return name; }

const를 붙여주면 더 좋다.

 

#include <iostream>
class Dog {
private:
	int age;
	std::string name;
public:
//	Dog() { age = 1; name = "강아지"; }
	Dog(int age=1, std::string name="강아지") { this -> age = age; this -> name = name; }
	int getAge() { return age; }
	void setAge(int age) {this -> age = age; }
	std::string getName() const { return name; }
	void setName(std::string name) { this -> name = name; }
};
int Dog::getAge() { 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,happy(3, "해피");
	std::cout << coco.getName() << coco.getAge() << std::endl;
	std::cout << happy.getName() << happy.getAge() << std::endl;
	coco.setName("코코");
	coco.setAge(1);
	happy.setName("해피");
	happy.setAge(2);
	std::cout << coco.getName() << coco.getAge() << std::endl;
	std::cout << happy.getName() << happy.getAge() << std::endl;
	return 0;
}

밖으로 빼서 써줄 수 있다.

 

#include <iostream>
class Dog {
private:
	int age;
	std::string name;
public:
//	Dog() { age = 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; this->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,happy(3, "해피");
	std::cout << coco.getName() << coco.getAge() << std::endl;
	std::cout << happy.getName() << happy.getAge() << std::endl;
	coco.setName("코코");
	coco.setAge(1);
	happy.setName("해피");
	happy.setAge(2);
	std::cout << coco.getName() << coco.getAge() << std::endl;
	std::cout << happy.getName() << happy.getAge() << std::endl;
	return 0;
}

최종 완성형이라고 볼 수 있다. const를 함수에 써주고 생성자를 public밖으로 꺼내어 작성했다.

 

'C++' 카테고리의 다른 글

12주차 강의내용  (0) 2024.11.19
12주차 예습과제  (0) 2024.11.18
11주차 예습과제  (0) 2024.11.11
10주차 강의 내용  (0) 2024.11.05
10주차 예습과제  (0) 2024.11.04