Data Type
OS 별(16bit/32bit/64bit) 크기 사용의 요점
- int는 시스템의 기본 연산 단위를 사용한다.(16 bit => 2 byte, 32 bit => 4 byte, 64 bit => 4byte)
- 64 bit에서 long 형은 8byte로 확장된다. (16 bit => 4byte, 32 bit => 4 byte, 64 bit => 8byte)
문자열 다루기
- 문자열 초기화
#include <string>
// 원본 문자열
string orgString = "TEST STRING";
- 문자열 복사
string tarString = orgString;
- 문자열 비교
if (tarString == orgString){
- 문자열 결합
addString = orgString + addString;
- 문자열 찾기
int stringIndex = addString.find("+ADD");
- 문자열 자르기
string cutString = addString.substr(12, 3);
형변환
- 명시적 형변환
float number1 = 55.55;
int number2 = (int)number1;
bool number3 = (bool)number1;
- 묵시적 형변환
// 그냥 대입한다.
float number1 = 55.55;
int number2 = number1;
bool number3 = number1;
OOP
객체지향 개념
객체지향 구성 요소
- class: 추상 자료형
- object: 추상 자료형의 인스턴스
- method: 정의된 연산
- message: method call
객체지향 특징
- 추상화: 객체의 핵심적인 부분만 표현하고, 세부 구현은 감추는 것.
- 캡슐화, 은닉화
- 데이터와 메서드를 하나로 묶고, 데이터를 보호하는 것.
- oop 프로그램은 캡슐화로 클래스 설계(인터페이스)와 사용(구현)을 구분한다.
class Calculator {
public:
virtual int addInt(int num)=0;
virtual string addStr(string str)=0;
};
class WinCalc: Calculator {
private:
int num; // 외부에서 직접 접근 불가
string str
public:
virtual int addInt(int _num) { // public 메서드를 통해 간접적으로 데이터 수정
return num + _num;
}
virtual string addStr(string _str) {
return str + _str;
}
};
- 상속: 기존 클래스를 기반으로 새로운 클래스를 만들어 코드 재사용성을 높이는 것.
class Study { // 부모 클래스
public:
void addInt() { /* 공통 기능 */ }
};
class Book : public Study { // 자식 클래스
public:
void addStr() { /* Book만의 기능 */ }
};
- 다형성: 같은 이름의 메서드가 상황에 따라 다른 방식으로 동작하는 것.
class Study {
public:
virtual void print() { // 부모 클래스의 가상 함수
cout << "Study With me" << endl;
}
};
class Book : public Study {
public:
void print() override { // 자식 클래스에서 재정의
cout << "Read Book With me" << endl;
}
};
객체 지향 vs 절차 지향 vs 함수형 프로그래밍
- 객체 지향 프로그래밍 (OOP):
- 객체를 중심으로 데이터를 처리하고, 캡슐화, 상속, 다형성 등을 통해 현실 세계의 개념을 반영하며, 코드 재사용성을 높임.
class Car {
public:
void drive() { /* 자동차가 운전하는 동작 */ }
private:
int speed; // 자동차의 속도
};
- 절차 지향 프로그래밍 (Procedural Programming):
- 함수와 절차에 따라 프로그램이 순차적으로 실행되며, 단순하고 직관적인 코드 흐름.
void driveCar() {
// 자동차를 운전하는 절차
}
int main() {
driveCar(); // 자동차 운전
return 0;
}
- 함수형 프로그래밍 (Functional Programming):
- 함수를 중심으로 상태 변화를 피하고, 순수 함수와 고차 함수 등을 활용하여 부작용 없이 코드를 구성.
객체 지향 구현
- 접근 제한자
- public: 모든 외부 코드에서 접근 가능.
- protected: 상속받은 클래스에서 접근 가능하지만, 외부에서는 불가능.
- private: 해당 클래스 내부에서만 접근 가능하고, 외부와 상속받은 클래스에서는 접근 불가능.
- 생성자, 소멸자
- 생성자(Constructor): 객체가 생성될 때 자동으로 호출되는 함수로, 객체의 초기화를 담당
- 소멸자(Destructor): 객체가 소멸될 때 자동으로 호출되는 함수로, 객체가 소멸되기 전에 리소스를 해제하거나 정리하는 작업을 수행
- this 포인터
- 멤버가 호출할 때 그 멤버가 속한 객체를 가리키는 포인터
- 멤버를 호출한 객체의 const 포인터
- 멤버함수를 수행하고 나서 그 결과로 객체 자신을 return 할 경우 return *this라고 하면됨
- 클래스 멤버 함수 내에서 다른 클래스에 자기 자신을 매개변수로 넘길 때 사용
void print() {
cout << this->num << " ";
cout << this->sname << " ";
cout << this->lcount << " ";
cout << endl;
}
- 함수 오버로딩
// Ex1> 클래스(Class)의 선언
class Study
{
public:
Study();
// Ex2> 생성자 오버로딩(Overloading)
Study(int x, int y)
{
this->x = x;
this->y = y;
}
- 함수 오버라이딩
class Study {
public:
// 가상 함수
virtual void show() {
cout << "This is Study" << endl;
}
};
// 파생 클래스: Book
class Book : public Study {
public:
// 오버라이딩된 함수
void show() override {
cout << "This is Book" << endl;
}
}
- 연산자 오버로딩
- 기존의 C++ 연산자(예: +, -, =, [] 등)를 사용자가 정의한 클래스의 동작에 맞게 재정의하는 것
- +,- 연산자 오버로딩
Study operator+(Study study1) {
Study retval;
this->num += study1.num;
return retval;
}
Study operator-(Study study1) {
Study retval;
this->num -= study1.num;
return retval;
}
- 할당 연산자(=) 오버로딩
void Entry::operator=(const string& str) {
def = str;
flag = true;
}
void Entry::operator=(const char* str) {
def = str;
flag = true;
}
- 배열 연산자([]) 오버로딩
Entry& Dict::operator[](const string& k) {
for (int i = 0; i < MaxEntries && entries[i].valid(); i++) {
if (entries[i].match(k))
return entries[i]; // 키에 맞는 Entry 반환
}
string not_found = "*** not in dictionary";
entries[i].add(k, not_found); // 새로 추가
return entries[i];
}
Entry& Dict::operator[](const char* k) {
string s = k;
return operator[](s); // string으로 변환 후 위 함수 호출
}
- 출력 연산자(<<) 오버로딩
ostream& operator<<(ostream& out, const Entry& e) {
out << e.word << " defined as: " << e.def;
return out;
}
ostream& operator<<(ostream& out, const Dict& d) {
for (int i = 0; i < Dict::MaxEntries; i++) {
if (d.entries[i].valid())
out << d.entries[i] << '\n';
}
return out;
}
상속
- public 상속:
- c++은 접근 제한자를 따로 지정하지 않으면 private 상속을 한다.
- 하지만 private 상속과 protected 상속은 거의 사용되지 않으며 일반적으로 public 상속을 한다.
- 다형성
- 다형성은 하나의 인터페이스로 여러 형태의 동작을 구현할 수 있게 하며, 특히 가상 함수를 통해 동적 바인딩을 실현
- 정적 다형성은 함수 오버로딩, 동적 다형성은 가상 함수를 통해 이루어진다.
- 추상클래스, 순수 가상함수
- 추상클래스:
- 하나 이상의 순수 가상 함수(Pure Virtual Function)를 포함한 클래스
- 추상 클래스는 객체를 생성할 수 없음
- 순수 가상 함수:
- 구현이 없고, 파생 클래스에서 반드시 오버라이딩해야 하는 함수. 함수 선언 끝에 = 0을 사용하여 선언
- 추상클래스:
// 추상 클래스
class Calculator {
public:
// 순수 가상 함수
virtual int addInt(int num)=0;
virtual string addStr(string str)=0;
};
// 자식 클래스 1
class WinCalc: Calculator {
public:
// 순수 가상 함수 구현 (오버라이딩)
virtual int addInt(int num) {
return num;
}
virtual string addStr(string str) {
return str;
}
};
// 자식 클래스 2
class UbuntuCalc: public Calculator {
public:
virtual int addInt(int num) {
return num + 123;
}
virtual string addStr(string str) {
return str + "123";
}
};
- 다중상속:
- 하나의 클래스가 두 개 이상의 클래스로부터 상속을 받는 것.
- 여러 부모 클래스로부터 기능을 상속받아 사용할 수 있음. 하지만 모호성 문제(같은 이름의 멤버 함수)가 발생할 수 있음.
- 모호성 문제는 범위 지정 연산자(::)를 사용하여 해결.
class A { public: void show() {} };
class B { public: void show() {} };
class C : public A, public B {
public:
void display() {
A::show(); // A 클래스의 show 호출
B::show(); // B 클래스의 show 호출
}
};
References
'ETC > 커뮤니티' 카테고리의 다른 글
[C++] C++ 객체 지향부터 Modern C++ 까지 # day 2 template, lambda, auto type 추론, nullptr (0) | 2024.09.26 |
---|