본문 바로가기

TIPS/C++

[TIPS] 7th 20160725

7번째 강좌정리입니다.

1. 접근제한자

- 외부 클래스에서 해당 클래스의 멤버변수와 멤버함수의 사용여부를 결성하기 위해 사용하는 것이 접근제한자이다.

- 멤버의 앞에 private, public, protected 키워드와 :를 함께 사용하여 명시하며, 클래스에서 어떤 접근 제한자도 명시하지 않은 경우에는 기본적으로 멤버가 private권한을 가진다.


private



age는 private에 존재하기 때문에 접근이 불가능하다.


public


외부 클래스에서 해당클래스 멤버의 접근이 가능하다. 주로, 멤버변수들은 외부클래스에 사용할 수 있도록 하는 인터페이스들을 public으로 선언한다.



2. THIS 포인터


다음과 같은 C언어코드를 C++로 바꾸면 아래와 같다.



- THIS 포인터는 현재 활성화된 객체의 주소를 가지고 있는 포인터이다.

클래스명 * const this;

- 클래스 내부에서 현재 작업 중인 객체의 멤버변수와 멤버함수에 접근하기 위해 컴파일러가 내부에서 선언한다.


만약 부득이하게 이름 중복이 된다면 아래와 같이 프로그래머가 this를 직접 써주는 것으로 해결할 수 있다. 하지만 이름중복은 없도록 하는 것이 좋다.


C언어에서는 지역변수와 전역변수의 명이 같을 때, 지역변수에만 접근이 가능하고 전역변수에는 접근이 불가능했다. 

C++에서는 ::data=5; 이런식으로 적어주게 되면 지역변수를 무시하고 전역변수에 접근하여 값을 바꿀 수 있다.

정리하자면 멤버는 this, 전역은 ::(스코프)를 사용한다.


3. THIS 포터의 상수화

- const 키워드를 함수 반환값 앞에 명시하는 경우 반환값이 상수화

- const 키워드를 함수 선언부 뒤에 명시하면 this포인터가 가리키는 값이 상수화



*참고.. reference 기술.


int data;

int &r=data;

r=5

이 코드는


int data;

int * const p =&data;

*p=5;

와 같은 의미이다. 하지만 reference 기술은 만든사람 말고 쓰는사람일 경우엔 주소가 넘어가는지 값이 넘어가는지 잘 알 수 없기 때문에 잘 쓰지 않게 된다.


4. 상속

- 웹페이지에서와 같이 프로그램을 작성할 때에도 많은 코드의 중복이 발생한다.

- 코드의 중복은 비슷한 기능을 하는 클래스의 코드를 그대로 복사해서 사용하기 때문에 많이 발생한다. 따라서 웹페이지의 링크와 같은 개념을 도입하여 중복된 코드를 쓰지 않도록 하는 것이 상속이다.

- 상속 문법을 사용하면 "동일한 코드가 명시한 곳에 있으니 이 클래스는 해당 클래스와 기본적으로 동일하다"는 뜻으로 컴파일러가 판단한다.

예를 들어 하나의 프로그램을 만들었는데, 각 지역마다 각각 다르게 코드가 변경되어야 하는 부분이 있다. 이럴 경우 흔히 쉬운 방법으로 일부 코드를 복사하고 변경하며 폴더를 만들며..후에는 점점 일이 커져 난리가 난다.


즉 복붙해서 수정하는 것이 제일 쉽지만 후에 일이 커지게 된다. 이럴 때 사용하는 것이 상속이고, 아래와 같이 사용한다.



class B는 자식클래스, class A는 부모 클래스이다.

public A의 public은 상속방식이다. A를 B에 복제한다는 뜻이다.

이렇게 하여 코드의 중복을 줄일 수 있다. 기계어로는 중복된다. 소스상 중복만 없어지게 된다. 이러한 것을 상속이라고 한다.


5. 상속등급

- 부모 클래스를 어떤 등급으로 상속하느냐에 따라 자식 클래스에서 부모 클래스 멤버에 접근할 수 있는 등급이 달라진다.

- protected 는 사용에 따라 접근 방식(접근 등급 상승)이 달라진다.

- 대부분의 경우 public상속 등급을 사용한다.



private는 상속되지 않는다. 상속을 사용하지 않을 경우에는 private와 protected는 동급으로 취급된다.

또한 private와 protected는 둘 다 보호되기 때문에 상속을 사용하는 경우에는 protected로 사용한다.


6. 오버로딩

- C++에서는 함수명 만으로 함수를 구분 짓는 C에서와는 다르게 인자의 개수나 인자의 데이터형을 달리하여 동일한 이름의 함수를 사용할 수 있도록 제공한다. 이것을 함수 오버로딩(Overloading)이라 한다.



첫번째 함수와 세번째 함수는 동일한 함수로 에러가 난다. 첫번째 함수와 두번째 함수는 다른 함수이다.


- 단, 함수의 반환형만 다른 경우에는 동일한 함수로 인식되기 때문에 주의해야 한다.


7. 오버라이팅

- 클래스 간의 상속관계에서 상위 클래스에 존재하는 함수를 하위 클래스에서 기능을 재정의하여 사용하는 것을 오버라이딩(overriding)이라고 한다.

- 오버라이딩은 오버로딩과 달리 함수의 이름, 인자의 개수, 인자의 데이터 타입이 정확히 일치해야 한다.


class B에 class A의 PrintName함수가 상속은 되지만 우선순위는 오버라이팅된 B의 PrintName함수가 더 높다.


부분상속을 원할 경우 위처럼 스코프연산자를 사용한다.


8. Allocation&Instance

- 할당 (Allocation)

메모리를 할당한다.

struct data;


-인스턴스(Instance)

메모리를 할당(allocation)함과 동시에 객체를 초기화한다.

B b;


9. 객체의 동적할당

-클래스를 사용하기 위해 동적으로 메모리를 할당하고 해제하는 방법에는 두가지가 존재한다.

첫번째 방법은 malloc-free함수를 이용하는 것이고, 두번째 방법은 new-delete연산자를 이용하는 것이다.


-malloc-free 함수

malloc-free함수를 이용하면 동적으로 메모리를 할당(allocation)하고 해제할 수 있지만 객체생성자와 객체파괴자가 정상적으로 수행되지 않기 때문에 클래스 객체 생성시에는 사용되지 않는다.



-new delete 연산자

클래스 객체를 동적으로 할당하고 초기화 하기위해(instance)사용되는 연산자로서, new연산자를 사용하여 객체를 생성하면 해당 객체는 heap 영역에 할당된다. new연산자로 할당한 메모리는 반드시 delete연산자로 해제해주어야 한다.


연산자는 언어가 직접 제공하는 기술이고 함수는 사용자가 만들어 쓰는 것이기 때문에 연산자가 더 처리속도가 빠르다.


int data[5]; 로 동적할당을 해주길 원한다면



10. scope 연산자



C++은 C와 달리 ::스코프연산자를 이용해서 지역변수대신 전역변수에 접근할 수 있다.



11. namespace

-C++에서는 함수나 변수의 이름이 중복되는 것을 막아주고, 코드의 가독성을 높이기 위해 namespace 라는 문법을 제공한다.

대규모 프로젝트에서는 반드시 namespace를 사용한다.


-매번 쓰기 귀찮으니 using이라는 키워드를 사용한다.



namespace 예제



★★12. 다형성



위와 같이 구조체와 포인터를 사용할 수 있다.

이를 아래와 같이 조금 다르게 사용해보자.


따라서 작은 포인터가 (A *p;) 큰 것(B temp2)를 가리키는 것은 문제가 없다. (문법오류로 걸러지기 때문에..)


이와 같은 개념으로

"부모 클래스(A)의 포인터가 자식클래스(A+α) 객체를 가리킬 수 있다."

를 다형성의 정의라고 볼 수 있다.


(예제)



오버라이딩할 때, 다형성이 적용될 때 virtual을 사용한다. 그렇다고 쓸대없이 사용하면 속도가 느려지니 필요할 때만 사용한다.


참고로 위에서 자식클래스에서 새로 추가된 함수는 접근하지 못한다.


그렇다면 다형성이 어떠한 경우에 유용한지 알아보자.

농장을 관리하는 프로그램이 있다고 생각해보자.

보통은 아래와 같이 클래스 하나에 상속하여 사용할 것이다.

(추상화)


여기서 다형성을 이용한다면



이런식으로 몇만라인이 되는 프로그램에서 if문이 다 없어지고 Animal을 중심으로 관리할 수 있다. 

동물이 추가되는 경우는 상속 관계만 하나 더 더해주면 된다.


하지만 여기서도 문제점이 하나 있다. 바로 Animal 자체가 바뀔 때는 상속된 class별로 다 바꿔주어야 한다는 것이다.






'TIPS > C++' 카테고리의 다른 글

[TIPS] 6th 20160721_(2)  (0) 2016.07.30