오늘의 목표

  • 아침 코드카타 풀기
  • C++ 문법 1-5 Class 개념 복습
  • C++ 문법 1-6 객체 지향 프로그래밍 강의 수강
  • C++ 문법 1-6 객체 지향 프로그래밍 복습
  • C++ 문법 1주차 과제

 

 

1. 코드카타

 

짝수와 홀수 문제

 

정수 num이 짝수일 경우 "Even"을 반환하고 홀수인 경우 "Odd"를 반환하는 함수, solution을 완성해주세요.

 

<주어진 코드>

#include <stdbool.h>
#include <stdlib.h>

int main() {
	// 리턴할 값은 메모리를 동적 할당해주세요
	char* answer = (char*)malloc(4 * sizeof(int));

	return 0;
}

 

<풀이 과정>

 

include <stdbool.h>
#include <stdlib.h>

int main() {
	// 리턴할 값은 메모리를 동적 할당해주세요
	char* answer = (char*)malloc(4 * sizeof(int));

	int num = 3;
	if (num % 2 == 0) {
		answer = "Even";
		
	}
	else {
		answer = "Odd";
	}


	free(answer);
	return 0;
}

 

이렇게 해 봤는데 오류가 발생했다.

<오류>

'=': 'const char [4]'에서 'char *'(으)로 변환할 수 없습니다.

'=': 'const char [5]'에서 'char *'(으)로 변환할 수 없습니다.

 

검색해보니 char* 타입의 메모리에 상수 문자열인 "Even"과 "Odd"를 대입하려 했기 때문에 생긴 문제로 보인다.

수정해본다.

또한 sizeof(int) * 4 로 메모리를 할당하지 않고 sizeof(char) * 5로 메모리를 할당하기로 한다 (1바이트는 null terminator 분량)

 

메모리를 저장할 때 answer = "Even"으로 직접 대입하는 게 아니라, strcpy를 사용한다.

그 이유는 문자열의 이름이 그 배열의 첫 번째 주소를 가리키는 주소값(상수)이기 때문에, = 연산자를 사용해 직접 문자열 전체를 대입할 수 없기 때문이다.

 

수정한 코드

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

int main() {
	// 리턴할 값은 메모리를 동적 할당해주세요
	char* answer = (char*)malloc(sizeof(char)*5);

	int num = 3;
	if (num % 2 == 0) 
    {
		strcpy(answer, "Even");
	}
	else 
    {
		strcpy(answer, "Odd");
	}


	free(answer);
	return 0;
}

 

<오류>

'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

 

해당 오류는 visual studio에서 발생하는 오류라고 한다. 프로그래머스에 넣으려면 코드를 조금 수정해야할 것 같아서 수정해보았다.

 

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

char* solution(int num) {
    // 리턴할 값은 메모리를 동적 할당해주세요
	char* answer = (char*)malloc(sizeof(char)*5);

	if (num % 2 == 0) {
		strcpy(answer, "Even");
		
	}
	else {
		strcpy(answer, "Odd");
	}

	return 0;
}

 

이대로 넣었는데 core dumped 오류가 발생한다. 

검색해보니 return 0 때문이라고 한다... 오케이...

 

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

char* solution(int num) {
    // 리턴할 값은 메모리를 동적 할당해주세요
	char* answer = (char*)malloc(sizeof(char)*5);

	if (num % 2 == 0) {
		strcpy(answer, "Even");
	}
	else {
		strcpy(answer, "Odd");
	}
    
    return answer;
}

이렇게 고치니 성공했다!

 

2. C++ 문법 1-5 Class 개념 복습

학습 목표

  • 클래스의 역할을 이해합니다.
  • 클래스와 객체를 정의하고, 이를 활용한 간단한 프로그램을 작성합니다.
  • 클래스 설계 시 접근 제어자(public, private)를 적절히 사용합니다.

 

class 없는 성적 관리 프로그램

#include <iostream>
#include <string>
using namespace std;

// 3 과목의 평균을 구하는 함수
double getAvg(int kor, int eng, int math)
{
	return (kor + eng + math) / 3.0f;k
}
//두 개의 수중 최대값을 반환하는 함수
int maxNum(int num1, int num2)
{
	if(num1 >= num2) return num1;
    else return num2;
}

// 3과목중 가장 높은 점수를 반환하는 함수
int getMax(int kor, int eng, int math)
{
	return maxNum(maxNum(kor, eng), math);
}

int main(){
	int kor[3];
    int eng[3];
    int math[3];
    
    for(int i = 0; i < 3; i++)
    {
    	cin >> kor[i] >> eng[i] >> math[i];
    }
    // 각 학생의 평균 점수와 과목 최대 점수를 출력
    for(int i = 0; i < 3; i++)
    {
    	cout << getAvg(kor[i], eng[i], math[i]) << endl;
        cout << getMax(kor[i], eng[i], math[i]) << endl;
    }
    
    return 0;
}

 

 

 

학생 클래스 정의

class Student
{
	// 동작 정의(이를 멤버함수라고 합니다)
    double getAvg();
    int getMaxNum();
    
    //데이터 정의(이를 멤버변수라고 합니다)
    int kor[3];
    int eng[3];
    int math[3];
};

 

 

 

멤버함수 구현 (클래스 내부)

#include <iostream>
#include <algorith> // max 함수 사용
#include <string>
using namespace std;
class Student
{
	// 동작 정의(이를 멤버함수라고 합니다)
    double getAvg()
    {
    	return (kor + eng + math) / 3.0;
    }
    
    int getMax()
    {
    	return max(max(kor, eng), math);
    }
    
    // 데이터 정의(이를 멤버변수라고 합니다.)
    int kor;
    int eng;
    int math;
};

 

 

 

멤버함수 구현 (클래스 외부)

#include <iostream>
#include <algorithm> // max 함수 사용
#include <string>
using namespace std;
class Student
{
	// 동작 정의(이를 멤버함수라고 합니다)
    double getAvg();
    int getMaxNum();
    // 데이터 정의(이를 멤버변수라고 합니다.)
    int kor;
    int eng;
    int math;
};

double Student::getAvg()
{
	return (kor + eng + math) / 3.0;
}
int student::getMaxNum()
{
	return max(max(kor, eng), math);
    // 다른 방법 return max({kor, eng, math});
}

 

 

 

private에 접근 시도

#include <iostream>
#include <algorithm> // max 함수 사용
#include <string>
using namespace std;

class Student
{
	//동작 정의(이를 멤버함수라고 합니다)
    double getAv();
    int getMaxScore();
    //데이터 정의(이를 멤버변수라고 합니다.)
    int kor;
    int eng;
    int math;
};

double Student::getAvg()
{
	return (kor + eng + math) / 3.0;
}

int Student::getMaxScore()
{
	return max(max(kor, eng), math);
}

int main()
{
	Student s;
    s.getAvg();
    
    return 0;
}

 

<오류>

'Student::getAvg': private 멤버('Student' 클래스에서 선언)에 액세스할 수 없습니다.

 

 

 

public, private으로 접근제어

#include <iostream>
#include <algorith> // max 함수 사용
#include <string>
using namespace std;

class Student
{
public:
	// 동작 정의(이를 멤버함수라고 합니다)
    double getAvg();
    int getMaxScore();

private:
	// 데이터 정의(이를 멤버변수라고 합니다.)
    int kor;
    int eng;
    int math;
};

double Student::getAvg()
{
	return (kor + eng + math) / 3.0;
}

int getMaxScore()
{
	return max(max(kor, eng), math);
}

int main()
{
	Student s;
    s.getAvg();
    
    return 0;
}

 

 

 

getter와 setter

getter와 setter를 적용한 class

#include <iostream>
#include <algorithm> // max 함수 사용
#include <string>

using namespace std;

class Student
{
public:
	double getAvg();
    int getMaxScore();
    
    void setMathScore(int math)
    {
    	this->math = math;
    }
    
    void setEngScore(int eng)
    {
		this->eng = eng;
    }
    
    void setKorScore(int kor)
    {
    	this->kor = kor;
    }
    
    int getMathScore() { return math; }
    int getEngScore() { return eng; }
    int getKorScore() { return kor; }
    
private:
	// 데이터 정의(이를 멤버변수라고 합니다.)
	int kor;
    int eng;
    int math;
};

double Student::getAvg()
{
	return (kor + eng + math) / 3.0;
}

int Student::getMaxScore()
{
	return max(max(kor, eng), math);
}

int main()
{
	Student s;
    
    s.setEngScore(32);
    s.setkorScore(52);
    s.setMathScore(74);
    
    // 평균 최대점수 출력
    cout << s.getAvg() << endl;
    cout << s.getMaxScore() << endl;
    
    return 0;
}

 

<예측 결과>

53
74

 

<출력 결과>

52.6667
74

 

첫째자리에서 반올림시켜버렸는데 실제로는 소숫점 다섯째자리에서 반올림한 값이 표시됨. 

 

 

 

생성자

정의된 class를 변수로 선언하면 해당 객체가 메모리에 올라간다.

이를 인스턴스화라고 한다.

 

 

 

기본 생성자

#include <iostream>
using namespace std;

class Person
{
public:
	string name;
    int age;
    
    // 기본 생성자
    Person()
    {
    	name = "Unknown";
        age = 0;
    }
    
    void display()
    {
    	cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main()
{
	Person p;	// 기본 생성자 호출
    p.display();
    return 0;
}

 

<예측 결과>

Name: Unknown, Age: 0

 

<출력 결과>

Name: Unknown, Age: 0

 

 

 

매개변수가 있는 생성자

#include <iostream>
using namespace std;

class Peerson
{
public:
	string name;
    int age;
    
    // 매개변수가 있는 생성자
    Person(string n, int a)
    {
    	name = n;k
        age = a;
    }
    
    void display()
    {
    	cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main()
{
	Person p("Alice", 25);	// 매개변수가 있는 생성자 호출
    p.display();
    return 0;
}

 

<예측 결과>

Name: Alice, Age: 25

 

<출력 결과>

Name: Alice, Age: 25

 

 

 

기본매개변수가 있는 생성자

#include <iostream>
using namespace std;

class Person
{
public:
	string name;
    int age;
    
    // 기본 매개변수가 있는 생성자
    Person(string n = "DefaultName", int a = 18)
    {
    	name = n;
        age = a;
    }
    
    void display()
    {
    	cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main()
{
	Person p1;	// 기본값 사용
    Person p2("Bob", 30);	// 값을 지정
    p1.display();
    p2.display();
    return 0;
}

 

<예측 결과>

Name: DefaultName, Age: 18
Name: Bob, Age: 30

 

<출력 결과>

Name: DefaultName, Age: 18
Name: Bob, Age: 30

 

 

 

잘못된 매개변수 전달로 에러 발생

#include <iostream>
using namespace std;

class Person
{
public:
	string name;
    int age;
    
    // 매개변수가 있는 생성자
    Person(string n, int a)
    {
    	name = n;
        age = a;
    }
};

int main()
{
	Person p("Tom"); // 에러: 생성자에 필요한 매개변수 부족
    // 컴파일 에러: "no matching function for call to Person::Person(const char [4])'"
    // 매개변수 두 개를 요구하는 생성자에 하나의 매개변수만 전달하여 매칭되지 않음
    p.display();
    return 0;
}

 

 

선언만 하지 정의하지 않아 에러 발생

#include <iostream>
using namespace std;

class Person
{
public:
	string name;
    int age;
    
    // 생성자를 선언만 하고 정의하지 않음
    Person(string n, int a);
};

int main()
{
	Person p("Alice", 25); // 선언된 생성자의 정의가 없으므로 컴파일 에러 발생
    cout << "Name: " << p.name << ", Age: " << p.age << endl;
    return 0;
}

 

 

기본 생성자를 잘못 호출해서 에러 발생

#include <iostream>
using namespace std;

class Person
{
public:
	string anme;
    int age;
    
    void temp() {}
    Person(string n, int a) {}
};

int main()
{
	Person p("a", 30);
    Person p2;
    
    p.temp();
    p2.temp();
    
    return 0;
}

 

<오류>

'Person': 사용할 수 있는 적절한 기본 생성자가 없습니다.

 

 

 

Student에 생성자 적용하기

과목점수 3개를 받는 생성자

#include <iostream>
#include <algorith> // max 함수 사용
#include <string>

using namespace std;

class Student
{
public:
	// 생성자
    Student(int math, int eng, int kor)
    {
    	this->math = math;
        this->eng = eng;
        this->kor = kor;
    }
    double getAvg();
    int getMaxScore();
    
    // 동작 정의 (이를 멤버함수라고 합니다)
    void setMathScore(int math)
    {
    	this->math = math;
       	// this.math = math; 와 동일
    }
    void setEngScore(int eng)
    {
    	this->eng = eng;
        // this.eng = eng와 동일
    }
    void setKorScore(int kor)
    {
    	this->kor = kor;
        // this.kor = kor와 동일
    }
    
    int getMathScore() { return math; }
    int getEngScore() { return eng; }
    int getKorScore() { return kor; }
   
private:
	// 데이터 정의(이를 멤버변수라고 합니다.)
    int kor;
    int eng;
    int math;
};

double Student::getAvg()
{
	return (kor + eng + math) / 3.0;
}

int Student::getMaxScore()
{
	return max(max(kor, eng), math);
}

int main()
{
	Student s(32, 52, 74);
    
    // 평균 최대점수 출력
    cout << s.getAvg() << endl;
    cout << s.getMaxScore() << endl;
    
    return 0;
}

 

<예측 결과>

52.6667
74

 

<출력 결과>

52.6667
74

 

 

 

기본값이 적용된 생성자

#include <iostream>
#include <algorithm> // max 함수 사용
#include <string>

using namespace std;

class Student
{
public:
	// 값이 주어지지 않을 경우 기본값을 할당하는 생성자
    Student(int math = 32, int eng = 17, int kor = 52)
    {
    	this->math = math;
        this->eng = eng;
        this->kor = kor;
    }
    double getAvg();
    int getMaxScore();
    
    //동작 정의(이를 멤버함수라고 합니다)
    void setMathScore(int math)
    {
    	this->math = math;
        // this.math = math와 동일
    }
    void setEngScore(int eng)
    {
    	this->eng = eng;
        // this.eng = eng와 동일
    }
    void setKorScore(int kor)
    {
    	this->kor = kor;
        // this.kor = kor와 동일
    }
    
    int getMathScore() { return math; }
    int getEngScore() { return eng; }
    int getKorScore() { return kor; }
    
private:
	// 데이터 정의 (이를 멤버변수라고 합니다.)
    int kor;
    int eng;
    int math;
};

double Student::getAvg()
{
	return (kor + eng + math) / 3.0;
}

int Student::getMaxScore()
{
	return max(max(kor, eng), math);
}

int main()
{
	Student s;
    //아래와 같이 사용할 수도 있음
    //Student s(1);
    //Student s(1, 2);
    //Student s(32, 52, 74);
    
    //평균 최대점수 출력
    cout << s.getAvg() << endl;
    cout << s.getMaxScore() << endl;
    
    return 0;
}

 

<예측 결과>

33.6667
52

 

<출력 결과>

33.6667
52

 

 

 

Student.h에 class 정의

#ifndef STUDENT_H_
#define STUDENT_H_
Class Student
{
	// 구현
};
#endif STUDENT_H_

#indef STUDENT_H_

STUDENT_H_가 정의되어있지 않은 경우에만 아래 코드를 수행하라는 의미

 

#define STUDENT_H_

STUDENT_H_를 정의한다

#ifndef #define이 수행되므로 단 한 번만 수행될 수 있다

 

#ifndef가 끝났다는 것을 알려주기 위해 #endif를 작성한다

 

Student Class는 중복 포함될 수 없게 된다.

 

Student class를 헤더파일에 정의 (Student.h)

#ifdef STUDENT_H_
#define STUDENT_H_
class Student
{
public:
	// 값이 주어지지 않을 경우 기본값을 할당하는 생성자
    Student(int math = 32, int eng = 17, int kor = 52)
    {
    	this->math = math;
        this->eng = eng;
        this->kor = kor;
    }
    double getAvg();
    int getMaxScore();
private:
	int kor;
    int eng;
    int math;
}
#endif

 

 

 

메인 함수에서 정의한 class 사용

 

소스파일(student.cpp)

#include "student.h"
double Student::getAvg()
{
	// 구현
}
int Studnet::getMaxScore()
{
	// 구현
}

 

메인(main.cpp)

#include "student.h"

//구현

 

 

 

Student class를 헤더파일에 정의 (Student.cpp)

#include "Student.h"
#include <algorithm> // max 함수

using namespace std;

double Student::getAvg()
{
	return (kor + eng + math) / 3.0;
}

int Student::getMaxScore()
{
	return max(max(kor, eng), math);
}

 

 

Student class를 헤더파일에 정의 (main.cpp)

#include <iostream>
#include "Student.h"

using namespace std;

int main()
{
	Student s;
    Student s2(1);
    Student s3(1, 2);
    Student s4(32, 52, 74);
    
    // 평균 최대점수 출력
    cout << s.getAvg() << endl;
    cout << s.getMaxScore() << endl;
    
    return 0;
}

 

<예측 결과>

33.6667
52

 

<출력 결과>

33.6667
52

 

 

숙제

숙제 1

C++로 간단한 배터리 관리 클래스를 만들어 보세요. 

#include <iostream>
#include <string>
using namespace std;

class Battery {
public:

	Battery(int initialCharge = 100) {
		charge = initialCharge;
	}
	int getCharge()
	{
		return charge;
	}
	void useBattery()
	{
		charge -= 5;
	}
	void chargeBattery()
	{
		charge += 7;
	}
private:
	int charge;
};

int main()
{

	Battery b;
	cout << "Initial charge: " << b.getCharge() << endl;

	b.useBattery();
	cout << "Battery used. Current charge: " << b.getCharge() << endl;
	b.useBattery();
	cout << "Battery used. Current charge: " << b.getCharge() << endl;
	b.chargeBattery();
	cout << "Battery charged. Current charge: " << b.getCharge() << endl;
	b.useBattery();
	cout << "Battery used. Current charge: " << b.getCharge() << endl;

}

 

배터리를 사용하고 충전하는 기능을 가진 class를 만들었다.

 

<예측 결과>

Initial charge: 100%
Battery used. Current charge: 95%
Battery used. Current charge: 90%
Battery charged. Current charge: 97%
Battery used. Current charge: 92%

 

<출력 결과>

Initial charge: 100
Battery used. Current charge: 95
Battery used. Current charge: 90
Battery charged. Current charge: 97
Battery used. Current charge: 92

 

%를 까먹고 안 썼다.

 

추가해주고 다시 출력해준다.

 

<최종 코드>

#include <iostream>
#include <string>
using namespace std;

class Battery {
public:

	Battery(int initialCharge = 100) {
		charge = initialCharge;
	}
	int getCharge()
	{
		return charge;
	}
	void useBattery()
	{
		charge -= 5;
	}
	void chargeBattery()
	{
		charge += 7;
	}
private:
	int charge;
};

int main()
{

	Battery b;
	cout << "Initial charge: " << b.getCharge() << "%" << endl;

	b.useBattery();
	cout << "Battery used. Current charge: " << b.getCharge() << "%" << endl;
	b.useBattery();
	cout << "Battery used. Current charge: " << b.getCharge() << "%" << endl;
	b.chargeBattery();
	cout << "Battery charged. Current charge: " << b.getCharge() << "%" << endl;
	b.useBattery();
	cout << "Battery used. Current charge: " << b.getCharge() << "%" << endl;

}

 

<출력 결과>

Initial charge: 100%
Battery used. Current charge: 95%
Battery used. Current charge: 90%
Battery charged. Current charge: 97%
Battery used. Current charge: 92%

 

<정답 확인>

정답과 다른 점 확인.

 

정답의 생성자 부분

Battery(int initialCharge = 100) : charge(initialCharge) // : 를 사용해서 대입했다. 생성자에 주로 사용하는 방식.

{
	if (charge < 0)
    {
    	charge = 0;
    }
    else if (charge > 100)
    {
    	charge = 100;
    }
}

// charge가 0보다 작거나 100보다 큰 경우에 범위 내로 설정하는 로직을 만들었다.

 

int getCharge() 부분

int getCharge() const	// 읽기만 수행하는 함수이므로 const
{
	return charge;
}

 

void useBattery()

void useBatter()
{
	if (charge >= 5) 
    {
    	charge -= 5;	
    }	// 배터리가 5프로 이상일 때 5씩 감소
    else
    {
    	charge = 0;
    }	// 배터리가 5프로 미만일 때 0으로 감소
    cout << "Battery used. Current charge: " << charge << "%\n";	// 출력 로직 포함
}

 

void chargeBattery()

void chargeBattery()
{
	if (charge <= 93)
    {
    	charge += 7;	
    }	// 배터리가 93프로 이하일 때는 7씩 충전
    else
    {
    	charge = 100;
    }	// 배터리가 93프로 초과일 시 100프로까지 충전
    cout << "Battery charged. Current charge: " << charge << "%\n"; // 출력 로직 함수에 포함
}

 

 

정답에서는 배터리가 0보다 작아지거나 100보다 커지지 않도록 하는 구체적인 로직을 구현했다.

코드 구현할 때 이런 부분까지 고려해서 구현할 것!

코드를 무턱대고 쓰지 말고 로직을 어떻게 구현할 지 구상하고 쓰면 좋을 것 같다.

 

숙제 2

두 분수의 곱셈을 할 수 있는 클래스 만듭니다.

<구상>

class Fraction

private 변수 numerator, denominator

Fraction():  기본 생성자

Fraction(num: int, denom: int): 분자와 분모의 값을 입력받는 생성자

simplify: 최대공약수를 구하는 함수를 이용해서 분수를 기약분수로 만든다. 최대공약수를 구한 뒤 분자와 분모를 각각 나누면 될 듯.

multiply(other: Fraction): Fraction: 두 분수를 곱하는 함수

display(): 함수를 출력한다.

 

<?> gcd(a: int, b: int): int

부분은 잘 모르겠다.

 

일단 이대로 구현해 보겠다.

 

<구현 과정>

Fraction Fraction::multiply(Fraction other)
{
	Fraction newFrac(0,1);
	newFrac.numerator = this->numerator * other.numerator;
	newFrac.denominator = this->denominator * other.denominator;
	//this->numerator *= other.numerator;
	return newFrac;
}

 

두 분수를 곱하는 함수에서 새로운 Fraction 인스턴스인 newFrac을 만들고, 해당 함수에 두 분수의 분자/분모 곱셈 값을 저장했다.

<주의>

인스턴스의 numerator에 접근할 때 .연산자를 사용하여 newFrac.numerator를 사용하면 된다.

this의 경우 자기 자신을 가리키는 포인터이기 때문에 -> 연산자를 사용하여 접근한다. 

 

#include <iostream>
#include <string>
using namespace std;

class Fraction 
{
private:
	int numerator;
	int denominator;

	int gcd(int a, int b);

public:
	Fraction() : numerator(0), denominator(1){}
	Fraction(int num = 0, int denom = 1)
	{
		numerator = num;
		denominator = denom;
	}

	void simplify();
	Fraction multiply(Fraction other);
	void display();
};

int Fraction::gcd(int a, int b)
{
	while (b != 0)
	{
		int temp = b;
		b = a % b;
		a = temp;
	}
	return a;
}

void Fraction::simplify()
{
	int newGCD = gcd(numerator, denominator);
	numerator /= newGCD;
	denominator /= newGCD;
}

Fraction Fraction::multiply(Fraction other)
{
	Fraction newFrac(0,1);
	newFrac.numerator = numerator * other.numerator;
	newFrac.denominator = denominator * other.denominator;
	//this->numerator *= other.numerator;
	return newFrac;
}

void Fraction::display()
{
	cout << "곱한 결과: " << numerator << "/" << denominator << endl;
}

int main()
{	
	//입력은 사용자로부터 직접 받지 않으며, 프로그램에 하드코딩 된 값으로 실행됩니다.
	Fraction f1(1, 2);
	Fraction f2(3, 4);

	Fraction result;
	result = f1.multiply(f2);

	result.display();
	
	return 0;
}

 

여기까지 작성했다. 그런데 자꾸 오류가 발생한다.

'Fraction::Fraction': 오버로드된 함수에 대한 호출이 모호합니다.

 

Fraction()과 Fraction(int num, int denom)의 구분이 모호해서 생기는 문제같다.

현재 Fraction()에서도 default (0, 1) 값으로 초기화를 하고 Fraction(int num = 0, int denom = 1)에서도 초기화를 하고 있기 때문이 아닐까?

 

Fraction()의 초기화 값을 일단 없애보겠다.

 

'Fraction::Fraction': 오버로드된 함수에 대한 호출이 모호합니다.

 

그래도 같은 오류가 발생하는 것이 확인되었다.

 

Fraction() 기본 생성자 자체를 삭제하고, Fraction(int num = 0, int denom = 1) 만 사용해보겠다.

 

#include <iostream>
#include <string>
using namespace std;

class Fraction 
{
private:
	int numerator;
	int denominator;

	int gcd(int a, int b);

public:
	//Fraction(); //: numerator(0), denominator(1){}
	Fraction(int num = 0, int denom = 1);
	
	//{
	//	numerator = num;
	//	denominator = denom;
	//}

	void simplify();
	Fraction multiply(Fraction other);
	void display();
};

//Fraction::Fraction()
//{
//	numerator = 0;
//	denominator = 1;
//}

Fraction::Fraction(int num, int denom)
{
	numerator = num;
	denominator = denom;
}

int Fraction::gcd(int a, int b)
{
	while (b != 0)
	{
		int temp = b;
		b = a % b;
		a = temp;
	}
	return a;
}

void Fraction::simplify()
{
	int newGCD = gcd(numerator, denominator);
	numerator /= newGCD;
	denominator /= newGCD;
}

Fraction Fraction::multiply(Fraction other)
{
	Fraction newFrac(0,1);
	newFrac.numerator = numerator * other.numerator;
	newFrac.denominator = denominator * other.denominator;
	//this->numerator *= other.numerator;
	return newFrac;
}

void Fraction::display()
{
	cout << "곱한 결과: " << numerator << "/" << denominator << endl;
}

int main()
{	
	//입력은 사용자로부터 직접 받지 않으며, 프로그램에 하드코딩 된 값으로 실행됩니다.
	Fraction f1(1, 2);
	Fraction f2(3, 4);

	Fraction result;
	result = f1.multiply(f2);

	result.display();
	
	return 0;
}

 

<출력 결과>

곱한 결과: 3/8

 

정상적으로 출력값이 나온다.

 

<정답 확인>

정답과 다른 부분을 비교해보자.

 

정답의 생성자

// 기본 생성자
    // 분자를 0, 분모를 1로 초기화합니다. (0/1은 0을 나타냄)
    Fraction() : numerator(0), denominator(1) {}

    // 매개변수가 있는 생성자
    // 사용자로부터 분자와 분모를 입력받아 초기화합니다.
    // 분모가 0일 경우 자동으로 1로 설정합니다. (분모가 0이면 정의되지 않음)
    Fraction(int num, int denom) {
        numerator = num;
        denominator = (denom != 0) ? denom : 1; // 분모가 0이면 1로 설정
    }

Fraction()과 Fraction(int num, int denom)을 함께 사용했다.

눈에 띄는 것은 입력된 denominator가 0일 경우 1로 바꿔서 division by 0 error를 방지했다는 점이다.

 

이 코드를 사용해서 이전의 오류가 사라지는지 확인해보자.

 

 

 

오류 없이 잘 컴파일 된다.

 

<개인 노트>

기본 생성자와 매개변수를 받는 생성자를 동시에 사용할 때, 매개변수를 받는 생성자의 default값을 인자를 받을 때 바로 설정하면 오류가 생기게 된다. (ex : Fraction(int num = 0, int denom = 1)) 

가능한 함수 내부의 로직으로 초기화할 것.

 

다른 부분은 큰 차이는 없는 것 같다. 과제 완료~

 

3. C++ 문법 1-6 객체 지향 프로그래밍 강의 수강

 

 

 

오늘의 배운 점: 기본 생성자와 매개변수를 받는 생성자를 동시에 쓸 때는 매개변수의 기본값을 인자를 받을 때 바로 설정하면 안된다. 반드시 함수 내에서 따로 설정할 것. (컴파일러가 인스턴스 초기화 시 어느쪽 함수를 쓰면 좋을지 헷갈려한다.)

 

오늘의 아쉬운 점: 수업 하나 복습하는 걸 거의 하루종일 붙잡고 있었다. 집중해서 시간을 줄여보는 걸 목표로 해야겠다.

+ Recent posts