Cplusplus 를 처음부터 복습 하면서, 이땐 그냥 그렇구나 라고 넘겼지만, 지금은 "왜?" 라는 생각이 드는 것들이 있을 수도 있고, 시험 전에 기본 개념에 대해서, 기본적이면서 필수적인 부분을 한번 더 상기시키기 위해 포스팅 하였습니다.
글 형식이 자유로워 읽기엔 다소 불편할 수 있습니다,,,
제가 공부할 때, 필요한 부분만 포스팅 되었으며,
제가 이해한 내용을 바탕으로 작성되었습니다, 혹여 다르게 해석되거나 틀린 부분이 있다면 댓글로 피드백 부탁드리겠습니다.
// 함수 호출
n = adder(24567,98374);
int adder(int a,int b){
int sum;
sum = a+b;
return sum;
}
포인터, 포인터란 주소를 가리킴.
*
를 사용해서 주소를 가리킴.
예,
int b =10;
int* a= &b;
// b가 저장된 메모리의 주소를 가리킴.
쉽게 설명하자면 int b 로 초기화하면 b 라는 변수에는 숫자 10이 저장됩니다.
즉, 변수에 저장된다는 것입니다. 근데 이 변수는 정수형으로 지정해줬으며, 메모리에 저장이 되어야합니다. 그래야 사용할 수 있으니까요.
즉, 변수는 n 이지만 주소값은 랜덤으로 아무 값이나 할당 받습니다.
이것은 찍어보면 알 수 있습니다. (&
)
따라서, 변수 b 를 가리키는 것이 아니라, 변수 b가 저장되어있는 메모리의 주소를 가리킨다고 보면 됩니다.
참고로, 변수 b 에는 여러 값이 할당 될 수 있습니다. (이게 포인트)
만약 int 형이라면 4 Byte를 저장할 수 있는 것입니다. 4Byte는 32 bit가 됩니다.
8bit는 1byte이기 때문이죠.
그러니까 int형으로 지정한 변수 n을 초기화 했다면, 4바이트의 메모리를 할당 받는 것입니다.
따라서, 이 메모리에 접근하려면 포인터를 사용하거나 변수를 사용하면 되는 것입니다.
(참고로 변수를 사용하면 메모리 직접접근이 아님)
데이터를 캡슐로 싸서 외부의 접근으로부터 보호함. (데이터 은닉)
클래스 (class
키워드)로 캡슐 표현.
보통 많은 책들이 예시로 붕어빵을 예시로 듭니다,
찍어내는 붕어빵 틀을 클래스(객체를 정의하는 틀),
객체 생성하여(붕어빵 생산), 다양한 색상의 붕어빵 (실체_객체들)
클래스 - 객체를 만드는 틀
객체 - 클래스라는 틀에서 생겨난 실체
객체 -실체
class Circle{
private:
int radius;
public:
Cricle(int r){
radius = r;
}
double getArea(){
return 3.14*radius*radius;
}
};
아, 맞다! 참고로, void는 리턴 값이 없다는거 알고 계시죠? ㅎㅎ 모른다면 이제 아시면 됩니다 !,,
참고로 c++은 c랑 다르게 void main() 을 하지 않고, int main()을 해야합니다 !
자식이 부모의 유전자를 물려 받는 것과 유사.
자바로 따지면 extends
로 상속할 수 있습니다.
하지만, c++은
class Phone{
void call();
void receive();
};
class MobilePhone : public Phone{ // Phone을 상속받습니다.
void connectWireless();
void recharge();
};
class MusicPhone : public MobilePhone{ // MobilePhone을 상속받음
void downloadMusic();
void play();
};
하나의 기능이 경우에 따라 다르게 보이거나 다르게 작동하는 현상.
연산자 중복, 함수 중복, 함수 재정의(overriding)
오버라이딩 / 오버로딩 차이점을 모르신다면,
꼭 집고 넘어가세요 !
이전에는 수학 계산이나 통계 처리에 편리한 절차지향 언어가 적합했습니다.
그러나,
현대의 SW는 물체 혹은 객체의 상호 작용에 대한 묘사가 필요,
실세계는 객체로 구성된 세계입니다. (모든 것이 객체라고 보면됨).
객체를 중심으로 하는 OOP가 적합함에 따라 도입되었습니다.
#
은 전처리자 라고하며 해당 언어에게 내리는 지시를 의미합니다.
#include <iostream>
전처리기 c++에게 내리는 지시. 헤더파일을 컴파일 전에 소스에 확장하도록 지시합니다.
using namespace std;
c++에서 정의한 이름공간 중 하나
표현 방식 : 2가지
\0
로 끝나는 문자 배열char name [6] = {'G','r','a','c','e','\0'};
또는
char name2[10] = "Grace";
// 이렇게 되면
로 저장됨.
<string>
헤더 파일에 선언됨.c언어에서 사용한 함수 사용 가능.
strcmp(), strlen(), strcpy() 등
을 사용하려며느 c++ 에선,
<cstring>
헤더 파일을 사용하는 것이 바람직하며,
이게 c++ 표준 방식입니다. 필자도 이를 권장합니다.
-> string 클래스는string
헤더파일 써야함. (오해 노노!)
char name[6];
// 5개의 문자를 저장할 수 있는 char 배열입니다.
왜냐하면, 마지막에 \0
이 포함되어 있기 때문입니다.
char name[11];
// 한글은 5개 글자, 영어는 10개 까지 저장할 수 있습니다.
cin.getline()
으로 공백이 낀 문자열 입력을 받을 수 있습니다.
cin.getline(char buf[], int size, char delimitChar)
\0
붙임\0
붙임\0
(Enter 키)char address[100];
cin.getline(address, 100, '\n'); // 최대 99개의 문자를 읽어,
// address 배열에 저장함. 도중에 ENTER 키를 만나면 입력 중단됨.
string
헤더 파일에 선언 해야 사용할 수 있습니다.getline()
은 string 타입의 문자열을 입력 받기 위해 제공되는 전역 함수입니다.
아래 예시를 통해 익혀보시면 될 것 같습니다.
이때, 중요한 것은 getline()
사용법과,+
로 문자열 연결 가능하며, 빈칸을 포함하는 문자열이 입력 가능하다. 라는 점입니다.
#include <iostream>
#include <string>
using namespace std;
int main() {
string song("Falling in love with you"); // 문자열 song
string elvis("Elvis Presley"); // 문자열 elvis
string singer; // 문자열 singer
cout << song + "를 부른 가수는"; // + 로 문자열 연결
cout << "(힌트 : 첫글자는 " << elvis[0] << ")?"; // [] 연산자 사용
getline(cin, singer); // 문자열 입력
if(singer == elvis) // 문자열 비교
cout << "맞았습니다.";
else
cout << "틀렸습니다. "+ elvis + "입니다." << endl; // +로 문자열 연결
}
![](https://velog.velcdn.com/images/ohoh7391/post/791008de-32aa-492a-abb7-230d3ad2bcaa/image.png)
참고 !,
c++ 객체는 멤버함수와 멤버변수로 구성됩니다.
이때, 멤버변수 = 객체의 상태, 멤버함수 = 객체의 행동 으로 구성됩니다.
멤버 변수
bool on = true;
int channel = 8;
int volume = 16;
멤버 함수
void powerOn()
void powerOff()
void increaseChannel()
void decreaseChannel()
Circle donut;
// 이름이 donut인 Circle 타입의 객체 생성donut.radius = 1;
// donut 객체의 radius 멤버 값을 1로 설정.
은, 객체 이름과 멤버 사이에 .
연산자 이며 값 설정double area = donut.getArea();
//donut 객체의 면적 알아내기.
객체 이름과 멤버사이 연산자, getArea()는 멤버함수 호출이젠 실전입니다.
파이팅 !
3-2 정답,
class Circle {
// 2개의 생성자 중복 선언
Circle(); // 클래스 이름과 동일
Circle(int r); // 리턴 타입 명기하지 않음.
};
// 생성자 함수 구현
// 매개 변수 없는 생성자
Circle::Circle() {
}
// 매개 변수를 가진 생성자
Circle::Circle(int r) {
}
여러 생성자에 중복 작성된 코드의 간소화를 위해 사용됨.
main.cpp
#include "Circle.h"
int main(){
Circle donut; // 매개 변수 없는 생성자 호출
double area = donut.getArea(); // 위임 생성자 호출함.
cout<< "donut 면적은" <<area <<endl;
Circle pizza(30); // 매개변수 있는 생성자 호출 거기에 30 대입함.
area = pizza.getArea();
cout <<"pizza 면적" <<area <<endl;
return 0; // 이부분은 제거해도 잘 작동함.
}
Circle.hpp
#ifndef CIRCLE
#include <iostream>
using namespace std;
class Circle
{
private:
/* data */
public:
int radius;
// 위임 생성자
Circle();
Circle(int r); // 타겟 생성자
double getArea();
~Circle();
};
// 위임 생성자
Circle::Circle():Circle(1){
}
Circle::Circle(int r){
radius =r;
cout << "Radius" << radius << "Circle CREATE"<<endl;
}
double Cirlce::getArea(){
return 3.14*radius*radius;
}
Circle::~Circle()
{
}
#endif // CIRCLE
위에 있는 이미지 로직이랑 비교하면서 확인하면됨.
다음 포인터 클래스의 멤버 x,y를 , 생성자 서두에 초기값으로 초기화하고,
위임 생성자를 이용하여 재작성
class Point{
int x,y;
public:
Point();
Point(int a,int b)
};
Point::Point(){
x=0; y=0;
}
Point::Point(int a, int b){
x=a; y=b;
}
재작성 코드
- 생성자는 꼭 필요할까요?
네, 필요합니다. c++ 컴파일러는 객체가 생성될 때, 생성자를 반드시 호출합니다.- 개발자가 클래스에 생성자를 작성해 놓지 않았다면 ?
컴파일러에 의해 기본 생성자가 자동으로 생성됩니다.
class Circle{
...
Circle(); // 기본 생성자
};
예제 3-6.
#include "Rectangle.h"
int main(){
Rectangle rect1;
Rectangle rect2(3,5);
Rectangle rect3(3);
if (rect1.isSquare()){
cout << "rect1은 정사각형입니다." << endl;
}
if (rect2.isSquare()){
cout << "rect1은 정사각형입니다." << endl;
}
if (rect3.isSquare()){
cout << "rect1은 정사각형입니다." << endl;
}
return 0;
}
이것을 보고 class를 만드시오.
(참고, 객체를 3개 초기화(=생성) 하니까, 생성자 3개 필요함.)
정답,
#ifndef RECTANGLE
#include <iostream>
using namespace std;
class Rectangle
{
private:
int width, height;
public:
Rectangle();
Rectangle(int w,int h);
Rectangle(int length);
bool isSquare();
~Rectangle();
};
Rectangle::Rectangle(){
width = height =1;
}
Rectangle::Rectangle(int w, int h){
width =w;
height=h;
}
Rectangle::Rectangle(int length){
width = height = length;
}
boo Rectangle::isSquare(){
if (width==height) return true;
else return false;
}
Rectangle::~Rectangle()
{
}
#endif //RECTANGLE
객체가 소멸되는 시점에서 자동으로 호출되는 함수
오직 한 번만 자동 호출, 임의로 호출할 수 없음.
객체 메모리 소멸 직전 호출됨.
즉, 소멸자는 객체가 사라질 때, 마무리 작업을 위한 것입니다.
소멸자는 매개 변수 없는 함수이며, 소멸자는 한 클래스 내에 오직 한 개만 작성가능합니다.
소멸자는 참고로 객체 생성의 반대순으로 소멸됩니다.
C 와 동일하지만,
#ifndef CIRCLE
#define CIRCLE
#endif
이렇게 해줘야 헤더 파일의 중복 include 문제를 조건 컴파일로 해결할 수 있습니다.