#include <iostream>
/** 문자열 관련 라이브러리*/
#include <string>
/** 배열의 사이즈를 가져오기 위한 라이브러리*/
#include <array>
/** C++ 표준 라이브러리*/
using namespace std;
/** 테스트를 위해서 Lion이라는 이름의 클래스를 정의해 주도록 합니다. */
class Lion
{
public:
// 생성자들을 정의해 준다.
// : 클론 되는 초기화 리스트로 멤버 변수의 초기화를 하고 있다.
// 변환 생성자라고도 한다.
Lion(int eyeSight) : m_EyeSight(eyeSight)
{
cout << " Lion(int) " << endl;
}
Lion(string name) : m_Name(name)
{
cout << "Lion(string)" << endl;
}
Lion(int eyeSight, string name) : m_EyeSight(eyeSight), m_Name(name)
{
cout << "Lion(int, string)" << endl;
}
void SetInfo()
{
cout << "EyeSight : " << m_EyeSight << ", Name : " << m_Name << endl;
}
// int 타입으로의 형병환 연산자 오버로딩이다.
// 형변환 함수라고도 한다
// 형변환 연산자 오버로딩은 형변환 연산자를 실행하는 동안에 객체 자체의 값을 바꾸지 않는다는
// 것을 보장하기 위해서 const 키워드를 붙여 준다.
operator int() const
{
return m_EyeSight;
}
// 문자열 타입으로 형변환 연산자 오버로딩이다.
// 형변환 함수 (type conversion function)라고도 한다.
// 형변환 연산자 오버로딩은 형변환 연산자를 실행하는 동안에 객체 자체의 값을 바꾸지 않는다는
// 것을 보장하기 위해서 const 키워드를 붙여 준다.
operator string() const
{
// to_string() : 매개 변수로 입력받은 값을 문자열로 변경해주는 함수이다.
string info = to_string(m_EyeSight) + " : " + m_Name;
return info;
}
private:
int m_EyeSight;
string m_Name;
};
// 전역범위에서 함수를 정의하도록 한다.
// 전역범위는 함수 밖을 의미한다.
void SetMessage(string info)
{
cout << "Info : " << info << endl;
}
int main()
{
/**
형변환은 C언어 스타일의 형변환과 C++ 스타일의 형변환이 있습니다.
C언어 스타일의 형변환은 2가지 종류가 있습니다.
1. 묵시적 형변환(Implicit Cast) : 컴파일러가 자동적으로 형변환을 시키는 것을 의미합니다.
주로 대입연산자에서 발생합니다.
2. 명시적 형변환(Explicit Cast) : 명시적으로 자료형을 직접 변경해 주는 것을 의미합니다.
변수 앞에 소괄호() 를 통해서 변경할 수 있습니다.
형변환은 3가지의 모습을 가지고 있습니다.
*/
/**
실수 타입을 정수 타입으로 형변환 합니다.
실수 타입도 4바이트이고 정수 타입도 4바이트이다. 하지만 실수 타입은 소수점 아래 값이 있기 때문에
실수 타입이 정수 타입보다 범위가 더 크다.
양동이물(실수)을 그릇에 넣는 것은 물이 넘칠지언정 상관이 없다.
형변환은 조심해야한다.
*/
float floatValue1 = 3.14159265f;
int intValue1 = floatValue1; // 묵시적 형변환
int intValue2 = (int)floatValue1; // 명시적 형변환
int intValue3 = int(floatValue1); // 명시적 형변환
cout << "floatValue1 : " << floatValue1 << endl;
cout << "float to int -> intValue1 : " << intValue1 << endl; // 3
cout << "float to int -> intValue2 : " << intValue2 << endl; // 3
cout << "float to int -> intValue3 : " << intValue3 << endl; // 3
cout << endl;
cout << endl;
// 실수 타입을 정수 타입으로 형변환 하면 실수 타입의 소수점 아래 값들이 모두 없어진다.
int intValue4 = 3.141592f;
float floatValue4 = 1024;
cout << "intValue4 : " << intValue4 << " , floatValue4 : " << floatValue4 << endl; // 3, 1024
cout << endl;
cout << endl;
// 평균을 구해보자
int Math = 90;
int Kor = 85;
int Eng = 95;
int History = 97;
int Sum = Math + Kor + Eng + History;
int Average = Sum / 4;
cout << "Sum : " << Sum << ", Average : " << Average << endl;
cout << endl;
cout << endl;
// 평균이 91.75가 나와야 하는데 , 91이 나온다
// 정수 / 정수 = 정수
// 실수 / 정수 = 실수
// 정수 / 실수 = 실수
// 실수 / 실수 = 실수
// 문장 수정
//int AverageScore = (float)Sum / 4; // 명시적 형변환, 값이 다르다
float AverageScore = (float)Sum / 4; // 명시적 형변환
cout << "Sum : " << Sum << ", Average : " << AverageScore << endl; // 367, 91.75
cout << endl;
cout << endl;
// 테스트를 위해 Lion이라는 클래스 정의
// 생성자 호출로 객체생성을 해준다.
// 객체 생성은 다양한 방식이 있다.
Lion lion1 = Lion(10);
Lion lion2(2);
Lion lion3 = 25;
lion3 = 30; // 변환 생성자에 의한 묵시적 형변환
Lion lion4 = (Lion)30; // 명시적 형변환
cout << endl;
cout << endl;
// 문자열을 매개 변수로 가지고 있는 생성자를 호출해 준다.
// C++은 C언어의 거의 모든 문법을 포함하는데
// C언어 때는 문자열 타입이 없었다.
// C언어 때는 블리언 타입도 없었다.
// 문자열을 기본 자료형이 아니다.
// 기본 자료형 : 변수를 선언하고 내가 값을 주지 않아도 기본 값이 주어진다.
// char, int, long, float, double, bool
// 문자열 타입은 외부 라이브러리이다. #include <string>
// 에러가 생기니 문자열 타입으로 명시적 형변환을 해준다.
//Lion lion5 = "Simba"; // x
Lion lion5 = (string)"Simba"; // 변환 생성자에 의한 명시적 형변환
Lion lion6 = string("KingLion");
lion6 = (string)"White"; // 변환 생성자에 의한 명시적 형변환
lion6 = string("Black");
cout << endl;
cout << endl;
// 정수 타입과 문자열 타입을 모두 매개 변수로 가지고 있는 생성자 호출하기
Lion lion7(30, "Simba");
Lion lion8 = { 25, "KingLion" };
lion8 = { 30, "White" };
Lion lion9{ 20, "Black" };
cout << endl;
cout << endl;
cout << "정수 타입을 매개변수로 가진 생성자로 객체 생성 " << endl;
// 문자열 타입을 선언하고 값을 주지 않으면 nullptr이다. 빈 문자열이 아니다
lion1.SetInfo();
lion2.SetInfo();
lion3.SetInfo();
lion4.SetInfo();
cout << endl;
cout << "문자열 타입을 매개변수로 가진 생성자로 객체 생성" << endl;
// 정수 타입에 쓰레기 값이 들어간다.
lion5.SetInfo();
lion6.SetInfo();
cout << endl;
cout << "정수 타입과 문자열 타입을 매개 변수로 가진 생성자로 객체 생성" << endl;
lion7.SetInfo();
lion8.SetInfo();
lion9.SetInfo();
cout << endl;
// 변환 생성자로 정수값을 Lion타입으로 형변환 해보자
// 반대로 Lion타입을 정수값으로 형변환 가능할까
// 에러가 나면서 변환이 되지 않는다.
//int intValue5 = lion9; // x
//int intValue6 = (int)lion9; // x 명시적 형변환
// 형변환 자체도 연산자이다 형변환 연산자이다.
// 연산자 오버로딩으로 해결할 수 있다.
// int 타입으로 형변환 연산자 오버로딩을 해 준다.
// 형변환 함수(type conversion)이라고 한다.
int intValue5 = lion9; // 암묵적(묵시적) 형변환
int intValue6 = (int)lion9; // 명시적 형변환
cout << endl;
// 문자열 타입을 Lion타입으로 형변환 하기
// 반대로 Lion타입을 문자열 타입으로 형변환하기 x
//string strLion8 = lion8; // x
//string strLion9 = (string)lion9; // x
cout << endl;
// 연산자 오버로딩을 해결 할 수 있다
// 문자열 타입으로의 형변환 연산자 오버로딩을 해 준다.
// 형변환 연산자 오버로딩을 형변환 함수 (type conversion function)라고도 한다.
string strLion8 = lion8; // 암묵정(묵시적) 형변환
string strLion9 = (string)lion9; // 명시적 형변환
// 다양한 방법으로 Lion 객체를 문자열로 변경해본다.
// Lion객체의 생성자 중 하나가 문자열을 매개 변수로 가지고 객체를 생성하기 때문이다
// 반대로 객체가 가지고 있는 문자열을 문자열 변수에 넣어주는 것이다.
string strLion = lion8;
// 지금까지는 C++에서 제공하는 기본적인 형변환이다
// 이후 상속에서의 형변환에 대해 알아보자.
// 객체지향 언어의 4대 특징
// 1. 캡슐화 : 멤버 변수의 보호
// 2. 상속
// 3. 다향성 : 가상함수와 동적 바인딩
// 4. 추상화 : 순수가상함수와 추상클래스
// SetMessage 함수는 매개변수로 문자열 타입이다.
// 따라서 Lion 객체가 문자열로 묵시적 형변환이 된다고 볼 수 있다.
SetMessage((string)lion8); // 명시적 형변환
cout << "(string)lion8 " << (string)lion8 << endl; // 명시적 형변환
cout << endl;
SetMessage(lion8); // 묵시적 형변환
cout << "lion8 : " << lion8 << endl;
cout << endl;
string strLion8 = lion8; // 묵시적 형변환
cout << "strLion8 : " << endl;
cout << endl;
}