오버로드 (Overload)
동일한 이름을 갖고있지만 다른 동작을 하게 만드는 것
대표적으로 함수 오버로드가 있다.
함수 이름은 함수명을 포함한 파라미터의 타입의 나열들 까지 포함
-> 파라미터의 개수나 타입이 다르다면 서로 다른 함수명이 된다.
함수 오버로드를 통해 이름은 같지만 서로 다른 파라미터에 대해 각각의 동작을 따로 지정해줄 수 있다.
파라미터의 개수와 타입을 통해서 어떤 함수가 불러 지는지를 특정할 수 있다.
클래스에서의 함수 오버로딩
이는 클래스 멤버함수에서도 동일하게 작용하게 된다.
또한 클래스 생성자에 대해서도 동일하게 작용할 수 있는데
이는 클래스가 여러 개의 생성자를 가질 수 있다는 것을 의미
클래스 생성자도 어찌보면 함수라 할 수 있고,
클래스 생성자도 파라미터의 타입과 개수를 통해 어떤 생성자를 호출할 수 있을지 결정할 수 있기 때문
클래스 생성자가 여러 개가 있을 경우 하나의 생성자만 호출해주면 된다.
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> class Student { public: int student_no; char student_name[100]; Student() { // 초기화 student_no = 0; strcpy(student_name, "아무개"); } Student (int studentNo, const char* student_name) { this->student_no = studentNo; strcpy(this->student_name, student_name); } void printInfo() { printf("%s 학생의 학생번호 : %d\n", student_name, student_no); } }; int main(){ Student* s1 = new Student(); Student* s2 = new Student(10, "홍길동"); // 10과 홍길동을 이용해 위의 파라미터가 있는 멤버 변수들을 초기화 해줬다. s2->printInfo(); // s2 출력 s1->printInfo(); // s1 출력 return 0; } |
연산자에서의 오버로딩
연산자 또한 오버로딩을 할 수 있는데
동적 클래스가 아닌 Stack 기반 클래스 인스턴스에 동작하는 연산자를 오버로딩 할 수 있다.
연산자 오버로딩의 가장 좋은 점은
연산자 오버로딩을 통해 우리가 현실세계에서 쓰는 것과 같은 표현을 컴퓨터에게 입력할 수 있다는 점이다.
연산자 오버로딩을 하게 되면 좌표, 벡터, 문자열 등에 대한 스택 기반 클래스 인스턴스에
덧셈 곱셈 뺄셈 등등의 여러 연산자를 집어넣을 수 있다.
본래 연산자라는 것은 어사인 (=) 연산자를 제외한 나머지 모든 연산은 '기본형 데이터 타입'에만 적용 가능
그런데 c++에서는 연산자 오버로딩을 통해 이 장벽을 넘을 수 있다.
다른 언어에서의 연산자 오버로딩
c / c++/ c#을 제외하면 다른 언어에서는 연산자 오버로딩을 마음껏 할 수 있는 환경을 찾아보기 어렵다.
특히 Java 같은 경우 이런 Vector 연산을 위해 긴 코드를 작성하거나 '멤버함수.add(...)'등을 호출하여 해결
2차원 벡터 연산
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> class Vector { public: float x; float y; Vector(float x, float y){ this->x = x; this->y = y; } Vector() { // 아무것도 받지 않는 생성자 x = 0.0f; y = 0.0f; } void printInfo(){ printf("%.2f, %.2f", x, y); } }; Vector operator+(Vector& v_1, Vector& v_2){ return Vector(v_1.x + v_2.x, v_1.y + v_2.y); } int main(){ Vector v1 = Vector(100, 200); Vector v2 = Vector(1, 2); Vector v3 = v1 + v2; v3.printInfo(); // 정적으로 만들어짐 연산자 오버로딩은 정적은 클래스 인스턴스에서만 동작 return 0; } |
3차원 벡터 클래스 (각각의 좌표에 해당하는 숫자에 10 곱하기)
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> class Vector3 { public: float x; float y; float z; Vector3(float x, float y, float z){ this->x = x; this->y = y; this->z = z; } Vector3() { // 아무것도 받지 않는 생성자 x = 0; y = 0; z = 0; } void printInfo(){ printf("%.2f, %.2f, %.2f", x, y, z); } }; Vector3 operator*(Vector3& v1, float s){ return Vector3(v1.x *s, v1.y *s, v1.z *s); } int main(){ Vector3 v = Vector3(10, 20, 30); Vector3 result = v * 10; result.printInfo(); return 0; } |
스칼라 (Scalar)
물리 / 수학적으로 어떤 양적인 수치를 의미
프로그래밍 초기에는 단순히 그냥 실수값이라 생각해도 무방
오버라이드 (Override) , 오버라이딩 (Overriding)
오버라이드 또는 오버라이딩은
부모 클래스의 함수의 정의를 자식 클래스에서 새로 덮어쓰는 것을 의미
(오버로딩은 완전히 서로 다른 이름을 만들어내는 것)
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> class Animal { public: int legs; char name[20]; Animal(int legs, const char* name) { // 초기화 this->legs = legs; strcpy(this->name, name); } void printInfo(){ printf("다리: %d, 이름 : %s\n", legs, name); } }; class Human : public Animal{ // 상속관계에서만 동작하는게 오버라이드 public: char regist_no[40]; Human(const char* regist_no) : Animal(2, "사람") { // 부모클래스에서 생성자를 정의했다면 그 생성자를 여기서 호출 strcpy(this->regist_no, regist_no); } // Human에서 다리개수, 이름 뿐만 아니라 주민번호까지 출력 하고 싶은 경우 -> Human에서 똑같은 이름으로 함수 만들기 void printInfo() { // 파라미터까지 똑같은 함수를 만들어 내는 것 : 오버라이드 printf("이름: %s, 주민등록번호: %s\n", name, regist_no); } }; int main(){ Human* human = new Human("1234-5678"); Animal* animal = new Animal(2, "닭"); human->printInfo(); // 오버라이드로 함수를 덮어씌웠기 때문에 주민등록번호 함수 실행 animal->printInfo(); // 다리와 이름만 나타남 return 0; } |
과제형 연습 프로그래밍
3차원 행렬 Matrix를 선언하고 이 Matrix의 정적 클래스 인스턴스의 행렬합을 구하는
연산자 오버로딩 함수를 구현하고 결과 출력
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> #include <cmath> #include <ctime> #include <cstring> class Matrix{ public: float v11, v12, v13; float v21, v22, v23; float v31, v32, v33; Matrix(float v11, float v12, float v13, float v21, float v22, float v23, float v31, float v32,float v33){ this->v11 = v11; this->v12 = v12; this->v13 = v13; this->v21 = v21; this->v22 = v22; this->v23 = v23; this->v31 = v31; this->v32 = v32; this->v33 = v33; } void printInfo() { printf("%.2f, %.2f, %.2f\n", v11,v12,v13); printf("%.2f, %.2f, %.2f\n", v21,v22,v23); printf("%.2f, %.2f, %.2f\n", v31,v32,v33); } }; // 연산자 오버로딩, 함수 선언 Matrix operator+(Matrix& m1, Matrix& m2); |
#include "lala.hpp" int main(){ Matrix m1 = Matrix(1,2,3,4,5,6,7,8,9); Matrix m2 = Matrix(10,11,12,13,14,15,16,17,18); Matrix result = m1 + m2; result.printInfo(); return 0; } // 연산자 오버로딩, 함수 몸체 Matrix operator+(Matrix& m1, Matrix& m2){ return Matrix( m1.v11 + m2.v11, m1.v12 + m2.v12, m1.v13 + m2.v13, m1.v21 + m2.v21, m1.v22 + m2.v22, m1.v23 + m2.v23, m1.v31 + m2.v31, m1.v32 + m2.v32, m1.v33 + m2.v33 ); } |
'C++' 카테고리의 다른 글
c++ 6 (열거형 - 가독성을 위한 타입) (0) | 2022.01.23 |
---|---|
c++ 5 (가상함수 - Java, C# 등 다른 언어의 개념 까지 ) (0) | 2022.01.16 |
c++ 3 (클래스 상속 / 접근지정자) (0) | 2021.09.24 |
c++ 2 (클래스 멤버 / 생성자 / 소멸자) (0) | 2021.09.08 |
c++ 1 (클래스 / 객체지향 - 게임 개발에 매우 중요한 개념) (0) | 2021.08.30 |