C and C++

C and C++

[C++] 복사 생성자와 복사 대입연산자의 차이점

class를 설계할 때 객체의 복사를 허용한다면, C++ 에서 객체를 복사하는 방법은 두가지가 있다. 1. 객체 생성시 복사 생성자를 이용하는 복사2. 복사 대입연산자를 이용하는 복사 두가지 방법의 미묘한 차이점이 존재하는데.코드를 통해 결론부터 말하면 다음의 예는 복사 생성자 Person p1(10, "ted");Person p2(p1); 또는Person p1(10, "ted"); Person p2 = p1; 다음의 예는 복사 대입 연산자이다. Person p1(10, "ted");Person p2(22, "Kong");p2 = p1; 복사 생성자의 두번째 예제와 복사 대입 연산자의 예제의 미묘한 차이점이 존재한다. 생성시기에 대입연산자 "="를 이용해서 대입을 하면 복사 생성자가 호출이 되고 생성후 ..

C and C++

[C++] new 연산자 예외처리

얼마전까지 c++로 개발 할 때 new연산에 대한 예외처리는 생각해보지 않고 개발했었다. 내공이 매우 부족하여 막연하게 프로그램 내에서 설마 new를 할 때 예외가 발생하겠어? 라는 생각을 가지고 있었다. 그러나 실무에서는 비일비재 한 일이였다. c++에서 new연산자에 대한 예외처리는 세가지이다. 1. try catch를 통한 예외 처리 try {int *arr = new int[100000000];}catch (std::bad_alloc &exception) {cout

C and C++

[C++] Template 템플릿에 대한 기본적인 이해

템플릿을 이용하면 일반화 프로그래밍이 가능해진다. 즉, 프로그래밍에서 일반화란 서로다른 데이터 타입들 간의 공통적인 성질을 뽑아 하나로 묶는 것을 말한다.여러가지의 데이터 타입들은 공통의 성질로 묶이게 되었으니 불필요한 중복이 없어지고 쉽게 구조화 되어 이해하기가 쉬워지는 장점이 있다. 아래의 간단한 예를 보면Calculator라는 클래스 템플릿이 사칙연산을 일반화 하였고 각각의 타입들이 사칙연산이라는 일반화의 틀(Template)에 묶인다. template class Calculator {public: Calculator(){} T add(T a, T b) { return a+b; } T sub(T a, T b) { return a-b; } T div(T a, T b) { return b>0 ? a/b..

C and C++

[C++] 상속에 대해

Java나 C#과는 다르게 C++는 다중 상속도 가능하며(권장 하지는 않지만) 상속자체에도 접근제한을 둘 수가 있다. 이러한 점이 다른 객체지향 언어보다 혼란스러운 이유이다.하지만 C++에서 상속관계를 고려할 때 Java나 C#의 방식과 비슷하게 상속관계를 생각해도 된다. 즉, 다중상속을 사용하지 않고 상속의 접근 제한자는 public 상속만 사용하겠다고 마음먹는 편이 편하다. 나 혼자 개발하면 위와 같이 생각하면 편하지만 여러 개발자랑 개발해야 하는 경우가 더 많기 때문에 여러가지 상속에 대해서도 알아둘 필요가 있어보인다.사실 다중상속은 경험이 부족해서인지 아직까지 실제로 쓰이는 것을 본적은 없다. 그나마 HAS-A 관계를 구현할 때 객체합성을 이용하거나 private 상속을 이용하는 경우가 있다. 일..

C and C++

[C++] 상속받은 비가상 함수를 재정의(override)하면 안된다.

java의 경우 기본이 virtual함수(메소드)지만 c++는 virtual이라는 키워드로 재정의 가능함에 대한 표시를 해준다.(+동적 바인딩을 통해 다형성을 구현)바꾸어 말하면 virtual가 아닌 비가상 함수의 경우 절대로 재정의를 하지 말라는 뜻이 된다. 따라서 상속을 허용하는 Base class에서 비가상 함수가 존재한다면 이는 "파생에 관계없이 불변의 동작을 정의"함을 의미한다.Base Class를 사용하는 사용자 입장에서는 절대로 비가상 함수에 대해서 재정의하려 들면 안된다. 그 이유는 비가상 함수는 가상 함수와 달리 정적으로 바인딩 되기 때문에 일관된 실행을 보장하지 못한다. 아래의 예를 통해 일관되지 못한 결과를 확인해보자. Base가 되는 Car Class class Car { publi..

C and C++

[C++] NVI (non-virtual interface) idiom 비가상 인터페이스에 대해

c++는 java나 c#처럼 interface 키워드를 이용해서 인터페이스를 구현 하지는 않지만 virtual함수를 통해 인터페이스를 구현한다.즉, 상속하고자 하는 Base class에 virtual 함수가 존재한다면 그 class를 상속해서 쓰는 쪽에서 virtual 함수를 마음껏 재정(override)의 해서 쓰면 된다는 의미이다.(반대로 virtual이 아닌 일반 함수의 경우 override하지 말라는 뜻이다.) 이렇듯 virtual함수를 통해 인터페이스를 제공하는 것은 일반적이다. 그러나 무조건 virtual함수 만을 이용해서 인터페이스를 구현하다보니 몇가지 문제점이 있다. 1. 개발자의 확장을 위한 virtual함수인지 사용자가 override해서 사용하는 함수인지 모호해 진다.(즉, 내가 만든..

C and C++

[C++] pImpl(pointer to implementation)를 이용해서 인터페이스와 구현을 분리하기

pImpl 방식을 활용해서 인터페이스와 구현을 분리할 수 있다. 그러면 왜 인터페이스와 구현을 분리 해야할까?여러가지 이유가 있겠지만 우선 헤더파일 안에 다른 헤더파일의 포함을 최소화 할 수 있어 컴파일 의존성을 최소화 할 수 있고(그러다보면 빌드 시간도 절약), 인터페이스와 구현내용간의 결합도가 떨어져서 유지보수에도 쉽다. 우선 인터페이스와 구현의 분리 개념의 예를 그림으로 보면 인터페이스 객체는 PhoneBook 관련해서 사용하는 쪽에 인터페이스를 제공하는 역할을 하는 class와 실제 그 기능이 구현되어 있는 역할을 하는 class로 나뉘게 된다. pImpl기법을 사용하면 하나의 기능을 제공하기 위해서는 아래와 같이 객체가 두개생성되는 비용이 발생하긴 한다. 간단하게 정리하면 실제 구현은 뒤로 숨기..

C and C++

[C++] C++ 스타일의 캐스트

기존의 c에서 캐스팅 방법은 (type)(표현식)으로 표현했다. 그러나 c++에서는 c++에서 제공하는 캐스트 연산자를 사용하고 c스타일의 캐스팅은 지양해야 한다.그이유는 다음과 같다.c 스타일의 캐스팅은 타입 안정성을 보장하지 못한다 (버그를 발생시킬 가능성이 매우 높다.)c++스타일의 캐스팅을 하면 가독성이 좋아진다. (project에서 ***_cast만 검색하면 된다.)c++스타일의 캐스트 연산자는 보다더 세부적인 캐스팅을 지원한다. 즉, 상황에 적절하고 세부적인 캐스팅을 지원하는 연산자이다.(c스타일의 캐스팅은 모든 범위를 포함)c++에서 제공하는 cast 연산자는 총 4개이다.const_cast dynamic_castreinterpret_caststatic_cast 1. const_castcon..

C and C++

[C++] 클래스를 캡슐화(Encapsulation) 하는 이유(왜 멤버변수는 대부분 private인가?)

객체지향 언어에서 클래스를 만들때 항상 나오는 말은 캡슐화(Encapsulation)다. 즉, 멤버변수는 private 접근 한정자로 외부의 직접적인 접근을 제한하고 클래스를 사용하는 외부에 인터페이스를 제공하여 직접 멤버변수를 접근하지 말자! 라는 의도이다.사실 학부시절에는 캡슐화를 해야하는 당위성에 대해서 의문점이 많았고 굳이 getter,setter 인터페이스를 제공해서 멤버변수를 접근할 필요없이 객체의 값을 잘 사용만하면 문제 될 것이 없지 않나? 라는 생각을 했었다. 좀더 공부를 해보니 다음과 같은 이유로 캡슐화는 필수적인 작업이었다. 1) 문법적 일관성을 제공한다.대부분의 개발자들이 멤버변수를 read하거나 write할 때 해당 데이터의 (만약 제공이 된다면)getter와 setter 함수를 ..

C and C++

[C++] 객체의 값을 전달할때 복사 비용을 줄이는 방법 "상수객체 참조자"

c++가 객체지향 언어지만 기반이 c이기 때문에 객체를 전달할때 값에 의한 전달(pass by value)을 제공한다. 객체를 값에 의한 전달을 할 경우 다음 두가지 문제가 발생한다. (생각해보니 vector등의 객체들은 그냥 값으로 전달한 기억이 있다.) 1) 복사생성자, 복사소멸자 + 객체안에서 객체를 사용할 경우 그 객체의 복사생성자, 복사소멸자 class Temp{ public: Temp(){ cout

자유로운 범고래
'C and C++' 카테고리의 글 목록 (2 Page)