C++ 기본 개념

다형성

서로 다른 객체가 동일한 기능을 서로 다른 방법으로 처리할 수 있는 기능을 의미한다.

자식 클래스에서 멤버 함수를 재정의하여 사용하는 것은 일반적으로 정상적으로 동작한다.
하지만 포인터 변수로 객체에 접근할 때에는 예상치 못한 결과가 발생할 수 있다.

C++컴파일러는 포인터 변수가 가리키고 있는 변수의 타입을 기준으로 함수를 호출하지 않고, 포인터의 타입을 기준으로 함수를 호출한다.
따라서 A라는 객체를 가리키는 포인터 변수는 A 객체의 멤버 함수만을 호출할 수 있다.

가상 함수

자식 클래스에서 재정의할 수 있는 멤버 함수.
Virtual 키워드를 이용해 선언하며 자식 클래스에서 가상 함수를 재정의하면 재정의된 멤버 함수 또한 가상 함수로 분류된다.
자식 클래스가 재정의할 가능성이 있는 멤버 함수들은 가상 함수로 선언하는 것이 좋다.

순수 가상 함수

가상 함수는 기본적으로 재정의할 필요는 없으나 순수 가상 함수는 자식 클래스에서 반드시 재정의해 주어야한다.
부모 클래스에서 함수 동작의 본체를 정의하지 않고 자식 클래스에서 정의해 주어야한다.
=0을 붙여 선언한다.

추상 클래스

하나 이상의 순수 가상 함수를 포함하는 클래스를 의미한다.
다형성을 효과적으로 구현 가능하게한다.

동적 바인딩

C++은 특정한 함수를 호출할 때 해당 함수의 루틴이 기록된 메모리 주소를 알아야한다. 특정한 함수를 호출하는 소스코드에서 실제로 함수가 정의된 메모리 공간을 찾기 위해서는 바인딩 과정이 필요하다.

일반적으로 함수 호출은 컴파일 시기에 고정된 메모리 주소를 이용한다. 이런 방식을 정적 바인딩이라고 하는데 c++의 일반적인 멤버 함수는 모두 이러한 정적 바인딩을 사용한다.

다만 가상 함수는 프로그램이 실행될 때 객체를 결정한다는 점에서 컴파일 시간에 객체를 특정할 수 없다. 그래서 가상 함수는 실행 시간 때 올바른 함수가 실행될 수 있도록 동적 바인딩을 사용한다.

일반화

C++은 템플릿을 이용해 일반화 프로그래밍이 가능하다

Generic이라고도 하는데 자료형과 상관없이 다방면으로 적용할 수 있게 해주는 역할을 한다.
다양한 타입에서 동작하는 하나의 객체를 정의할 수 있어 코드의 재사용성을 극대화할 수 있는 기법이다.

Ex)
#include <iostream>
#include <string>

using namespace std;

template <typename T> //자료형을 설정해 주지 않았으나 main에서 설정한 string타입이 들어간다.

void change(T& a, T& b) {
	T temp;
	temp = a;
	a = b;
	b = temp;
}

int main(void) {
	string a = "kim";
	string b = "park";
	change(a, b);
	cout << a << ":" << b << endl;
	system("pause");
}

클래스 템플릿

자료형에 따라서 다르게 동작하는 클래스 집합을 만들 수 있다.

Ex)
#include <iostream>
#include <string>

using namespace std;

template <typename T>

class Data {
private:
	T data;
public:
	Data(T data) : data(data){ }
	void setData(T data) { this->data = data; }
	T getData() { return data; }
};

int main(void) {
	Data<int> data1(1);
	Data<string> data2("kim");
	cout << data1.getData() << ":" << data2.getData() << '\n';
	system("pause");
}

스마트 포인터

프로그래머의 실수로 메모리 누수를 방어하기 위한 수단, 포인터처럼 동작하는 클래스 템플릿이다.

기본적으로 힙 영역에 동적 할당된 메모리를 해제하기 위해서는 delete키워드를 쓰면 된다.
스마트 포인터를 사용하면 메모리 누수를 더 효과적으로 방지할 수 있기 때문에 컴퓨터 시스템의 안정성을 높일 수 있다.

New키워드를 이용해 기본 포인터가 특정 메모리 주소를 가리키도록 초기화 한 후 스마트 포인터에 해당 포인터를 넣어 사용할 수 있다.

  • Unique_ptr – 하나의 스마트 포인터가 특정한 객체를 처리할 수 있게 해준다.
  • Shared_ptr – 특정한 객체를 참조하는 스마트 포인터가 총 몇 개인지 참조한다.
  • Weak_ptr – 하나 이상의 shared_ptr 인스턴스가 소유하는 객체에 대한 접근을 제공한다.

STL 컨테이너 어댑터

활용도가 높은 자료구조를 제공한다.
#include <>로 사용한다.

  • Stack - push, pop, top, empty, size등을 제공
  • Queue – push, pop, front, back, empty, size등을 제공
  • Priority queue - 내에 존재 priority_queue<>로 선언 후 사용

STL 시퀀스 컨테이너

마찬가지로 활용도가 높은 자료구조를 제공한다.

  • Deque – 양 끝에서 데이터를 삽입 삭제가 가능한 자료구조 push_front, push_back, pop_front, pop_back등이 가능하다.
  • Vector – 뒤에서만 데이터를 삽입 삭제가 가능하다. 배열처럼 사용되어 유용하게 쓰이는 자료구조이다. Push_back, pop_back등이 가능하다.

STL 연관 컨테이너

  • Set - 저장하는 데이터를 키로 사용하는 연관 컨테이너이다. 정렬된 위치에 데이터를 삽입한다는 점에서 검색 속도가 빠르다는 장점이 있다. 키의 중복은 불가능하다.

  • Map – 저장하는 데이터를 키와 값 쌍의 형태로 사용하는 연관 컨테이너이다. 정렬된 위치에 데이터를 삽입한다는 점에서 검색 속도가 빠르다는 장점이 있다. 키의 중복은 불가능하다.

예외 처리

예외란 프로그램 동작 과정에서의 오류를 의미한다.
Try catch 문으로 예외 처리를 수행한다.

  • Try – 특정 코드에서 예외가 발생할 수 있음을 명시
  • Catch – 발생한 예외에 대해서 핸들러가 특정한 내용을 처리
  • Throw – try 구문에서 발생한 오류를 전달

소켓

전구나 형광등을 고정하는 도구이자 전기를 공급하기 위한 투입구
컴퓨터 네트워크에서 통신을 위한 종착지와 같은 역할을 수행하며 두개의 컴퓨터가 통신할 때 각 컴퓨터의 소켓을 통해 데이터를 교환한다.
크게 TCP 와 UDP로 나뉜다.

TCP

Transmission Control Protocol의 약자 속도가 다소 느리지만 신뢰성 있는 데이터의 송수신을 보장한다. 인터넷 내에서 데이터를 주고받을 때 경로 설정을 효과적으로 수행하기 위해 데이터를 여러 개의 패킷으로 나누어 송수신한다.

UDP

User Datagram Protocol의 약자 비연결형 프로토콜로 신뢰성은 부족하나 빠른 송수신이 가능하다. 데이터를 주고받기 전에 사전 통신 절차를 거치지 않는다.

포트

특정한 프로그램이 통신을 하기 위해서는 포트 번호를 할당해야한다. 포트 번호는 16비트이며 1~1024번은 시스템 포트로 사용된다.

소켓 프로그래밍 함수

Socket(네트워크 주소체계, 소켓 타입, 프로토콜)

소켓을 생성하는 함수이다. 네트워크 주소체계, 소켓 타입, 프로토콜로 초기화가 가능하다. 소켓 생성에 실패하는 경우 -1을 반환한다.

Bind(소켓 변수, 서버 주소 구조체, 서버 주소 구조체의 크기)

서버 측의 소켓에 ip와 포트 번호를 할당하여 네트워크 인터페이스와 묶일 수 있도록한다.
소켓 주소 구조체를 이용할 때는 IPv4 소켓 주소 구조체를 일반 소켓 구조체(SOCKADDR)로 변환하여 사용해야한다.

Listen(소켓 변수, 백 로그 큐의 크기)

클라이언트로부터 연결 요청을 기다린다. 백 로그란 동시에 연결을 시도하는 최대 클라이언트 수를 의미한다.

//이 단계까지 완료되면 서버 생성이 완료되어 소켓을 열어 놓은 상태가 된다.

Connect(소켓 변수, 서버 주소 구조체, 서버 주소 구조체 크기)

클라이언트 측에서 서버에 연결을 요청한다. 소켓 생성에 실패하는 경우 -1을 반환한다.
소켓 주소 구조체를 이용할 때는 IPv4 소켓 주소 구조체를 일반 소켓 구조체(SOCKADDR)로 변환하여 사용해야한다.

Accept(소켓 변수, 클라이언트 주소 구조체 변수, 클라이언트 주소 구조체 크기)

서버 측에서 클라이언트 연결을 수락한다.
Accept()함수 내부에서 클라이언트 주소를 설정한 뒤에 통신에 사용할 클라이언트 소켓을 반환한다. 오류 발생시 -1을 반환한다.
소켓 주소 구조체를 이용할 때는 IPv4 소켓 주소 구조체를 일반 소켓 구조체(SOCKADDR)로 변환하여 사용해야한다.

Send(소켓 변수, 문자열 버퍼, 문자열 버퍼 크기, 플래그)

상대방에게 데이터를 보낸다. 특정한 소켓으로 문자열 버퍼에 담긴 내용을 전송한다.
플래그는 중요한 메시지를 보내는등 특정한 경우를 제외하면 0을 설정한다.
데이터 전송에 실패시 -1을 반환한다.

Recv(소켓 변수, 문자열 버퍼, 문자열 버퍼 크기, 플래그)

데이터를 수신하여 특정 문자열 버퍼에 담는다.
플래그는 중요한 메시지를 보내는등 특정한 경우를 제외하면 0을 설정한다. 데이터 전송에 실패시 -1을 반환한다.

Closesocket(소켓 변수)

열린 소켓을 닫는다.

Winsock2

윈도우에서 소켓을 사용하기 위해 만들어진 라이브러리
WSAStartup()함수 등을 통해 환경 설정을 진행해야한다.

좋은 웹페이지 즐겨찾기