객체지향 프로그래밍은 모든 데이터를 겍체로 취급하여 프로그래밍 하는 방법으로, 처리 요구를 받은 객체가 자기 자신의 안에 있는 내용을 가지고 처리하는 방식이다.
클래스와 객체
클래스와 객체는 '붕어빵 틀'과 '붕어빵'의 관계다. 혹은 '제품의 설계도'와 '제품'의 관계라고 말할 수도 있다. 클래스는 구조체와 거의 같은 개념으로 함수까지 멤버로 넣어서 사용한다는 점이 다르다. 즉 변수와 함수들을 하나의 가방에 모아놓은 것이 클래스다. 우리가 어떤 클래스를 만들어서 정의하면, 그 클래스는 새로운 타입이 되는 것이다.
// 간단한 클래스와 객체 예제
#include <iostream>
using namespace std;
// 클래스를 정의
class Point
{
public:
int x, y;
void Print();
};
// 멤버 함수 정의
void Point::Print()
{
cout << "(" << x << ", " << y << ")\n";
}
int main()
{
// 객체를 생성
Point pt1, pt2;
// pt1, pt2를 초기화 한다.
pt1.x = 100;
pt1.y = 100;
pt2.x = 200;
pt2.y = 200;
// pt1, pt2의 내용을 출력한다.
pt1.Print();
pt2.Print();
return 0;
}
// 멤버 함수 안에서의 이름 충돌
#include <iostream>
using namespace std;
// 클래스 정의
class Point
{
public:
int x, y;
void Print();
};
// 멤버 함수 정의
void Point::Print()
{
int x = 333;
cout << "(" << x << ", " << y << ")\n";
}
int main()
{
// 객체 생성
Point pt1, pt2;
// 객체 초기화
pt1.x = 100;
pt1.y = 100;
pt2.x = 200;
pt2.y = 200;
pt1.Print();
pt2.Print();
return 0;
}
// 멤버 변수와 같은 이름의 지역변수들을 사용할 경우 나타나는 문제점을 보여주는 예제이다.
생성자와 소멸자
생성자와 소멸자는 특별한 기능을 가진 멤버 함수다. 생성자는 객체를 생성할 때 자동적으로 호출되는 함수고, 소멸자는 객체가 소멸될 때 자동으로 호출되는 함수다.
// 디폴트 생성자
#include <iostream>
using namespace std;
class Point
{
public:
int x, y;
// 멤버 함수
void Print();
// 생성자
Point(); // 디폴트 생성자
};
// 멤버 함수 정의
void Point::Print()
{
cout << "(" << x << ", " << y << ")\n";
}
// 디폴트 생성자 정의
Point::Point()
{
x = 0;
y = 0;
}
int main()
{
Point pt;
pt.Print();
return 0;
}
// 디폴트 생성자에 의해서 x, y 멤버 변수가 0으로 초기화 된걸 알 수 있다.
// 인자가 있는 생성자
#include <iostream>
using namespace std;
class Point
{
public:
int x, y;
// 멤버 함수
void Print();
// 생성자
Point(); // 디폴트 생성자
Point(int initialX, int initialY); // 인자가 있는 생성자
};
// 멤버 함수 정의
void Point::Print()
{
cout << "(" << x << ", " << y << ")\n";
}
// 디폴트 생성자 정의
Point::Point()
{
x = 0;
y = 0;
}
// 인자가 있는 생성자 정의
Point::Point(int initialX, int initialY)
{
x = initialX;
y = initialY;
}
int main()
{
Point pt(3, 5);
pt.Print();
return 0;
}
// 복사 생성자
#include <iostream>
using namespace std;
class Point
{
public:
int x, y;
// 멤버 함수
void Print();
// 생성자
Point();
Point(int initialX, int initialY);
// 복사 생성자
Point(const Point& pt);
};
void Point::Print()
{
cout << "(" << x << ", " << y << ")\n";
}
Point::Point()
{
x = 0;
y = 0;
}
Point::Point(int initialX, int initialY)
{
x = initialX;
y = initialY;
}
// 복사 생성자 정의
Point::Point(const Point& pt)
{
x = pt.x;
y = pt.y;
}
int main()
{
Point pt1(100, 100), pt2(200, 200); // 인자가 있는 생성자 호출
Point pt3 = pt1; // 복사 생성자 호출
pt3.Print();
pt3 = pt2;
pt3.Print();
return 0;
}
FND 실습
1. 앞의 예제를 수정하여, 버튼을 누르면 2개의 FND가 동일한 숫자를 표시하도록 하기
#include "port.h"
int main(void)
{
DDRF = 0xff;
PORTF = 0xff;
volatile unsigned char i = 0;
volatile unsigned char j = 0;
volatile unsigned char a = 0;
while(1)
{
i = 0;
a = ~PINC;
while(a >= 1)
{
a /= 2;
i++;
}
j = i;
j <<= 4;
PORTF = j | i;
}
return 1;
}
2. 0~99까지 순차적으로 숫자를 1씩 증가하면서 FND에 표시 하기
#include "delay_m.h"
#include "port.h"
int main(void)
{
unsigned char fnd1 = 0x00;
unsigned char fnd2 = 0x00;
DDRF = 0xff;
PORTF = 0x00;
while(1)
{
PORTF = fnd2 | fnd1;
fnd1++;
if(fnd1 >= 0x0A)
{
fnd1 = 0x00;
if(fnd2 == 0x90)
{
fnd2 = 0x00;
}
else
{
fnd2 += 0x10;
}
}
delay(600);
}
return 0;
}
3. 0~99까지 순차적으로 숫자를 1씩 증가시키다가 버튼을 누르면 0부터 다시 시작하기.
#include "port.h"
int main(void)
{
unsigned char fnd1 = 0x00;
unsigned char fnd2 = 0x00;
DDRF = 0xff;
PORTF = 0x00;
DDRC = 0x00;
PORTC = 0x00;
while(1)
{
if((PINC & 0x01) == 0)
{
fnd1 = 0x00;
fnd2 = 0x00;
PORTF = 0x00;
}
else
{
PORTF = fnd2 | fnd1;
fnd1++;
if(fnd1 >= 0x0A)
{
fnd1 = 0x00;
if(fnd2 == 0x90)
{
fnd2 = 0x00;
}
else
{
fnd2 += 0x10;
}
}
delay(600);
}
}
return 0;
}