프로그래밍 언어/C & C++ 정리 99

Static 링크 :외부 링크와 내부 링크

static링크를 설명하기 전에 먼저C++에서 링크를 처리하는 과정을 이해할 필요가 있다.C++ 코드는 소스 파일 단위로 컴파일해서생성된 객체 파일을 링크 단계에서 서로 연결한다.함수나 글로벌(전역) 변수처럼C++ 소스 파일마다,정의된 이름은 외부 링크나 내부 링크를 통해 서로 연결된다.외부 링크외부 링크로 연결되면 다른 소스 파일에서 이름을 사용할 수 있다.내부 링크(= 정적 링크)내부 링크(=정적 링크)로 연결되면같은 파일에서만 사용할 수 있다.함수나 글로벌 변수는 기본적으로 외부 링크가 적용된다.하지만 선언문 앞에 static키워드가 붙이면내부 링크(=정적 링크)가 적용된다.익명 네임스페이스를 이용하여 내부 링크 적용앞서 말했듯이 내부 링크로 연결되면 같은 파일 내에서만 사용 가능하다고 했다.이는 ..

마이크로 소프트에서 사용되는 _CLRCALL_OR_CDECL

_CLRCALL_OR_CDECL 는 으래 C++에서 쓰이는 endl을 타고 들어가면 볼 수 있는 매크로이다. enld을 타고 들어가면 다음과 같은 코드를 볼 수 있는데, 해당 코드에서 사용되는 basic_ostream의 클래스 크기는 1바이트이다.아마 c의 _Alignof나 C++의 alignof(T) 또는 alignas를 사용한 것 같다. alignas의 예시 alignas를 사용하지 않고 클래스 패딩 규칙에 따른 메모리 할당 크기 alignas를 사용하여 메모리 할당 크기를 사용자가 임의로 지정해 준 코드 해당 코드 전문class a{ int v[4];};// V의 메모리 풀 즉, 패딩을 내가 조절하는 것// alignas를 사용하면// V의 할당 될 메모리를 비트 단위로 내가 할당해..

순수 가상 메서드와 추상 베이스 클래스

순수 가상 메서드란 클래스 정의 코드에서명시적으로 정의하지 않는 메서드이다.메서드를 순수 가상 메서드로 만들면,컴파일러는 이 메서드에 대한 정의가 현재 클래스에는 없다고 판단한다.순수 가상 메서드가 하나라도 정의된 클래스를 추상 클래스라 부른다.추상 클래스는 다른 코드에서 인스턴스를 생성할 수 없다.클래스에 순수 가상 메서드가 하나라도 있으면컴파일러는 이 클래스가 객체를 생성하는데 사용되지 않는다고 생각한다.순수 가상 메서드를 지정하려면 선언 뒤에 =0 을 붙인다.그리고 구현 코드는 작성하지 않는다.

virtual 키워드 메서드

virtual 메서드 동작방식override하지 않고 상속 관계의 자식클래스가같은 이름의 함수를 정의하면,각각의 동일한 이름의 함수가 재정의되지 않고 개별적으로 존재한다.이처럼 메서드를 가리는 일을 방지하려면virtual 키워드가 내부적으로 처리되는 과정을 이해할 필요가 있다.C++에서 클래스를 컴파일하면그 클래스에 있는 메서드를 모두 담은 바이너리 객체가 생성된다.그런데 컴파일러는 virtual로 선언하지 않은 메서드를 호출하는 부분을 컴파일 시간에 결정된 타입의 코드로 교체한다.이를 정적 바인딩 또는 이른 바인딩이라 부른다.메서드를 virtual로 선언하면vtalble(가상 테이블)이라 부르는 특수 메모리 영역을 활용해서가장 적합한 구현 코드를 호출한다.virtual 메서드가 하나라도 정의된 클래스에..

상속을 이용한 클래스 구현

클래스에 상속이 없다면 구조체에 동작만 추가한 것에 불과하다.그것만으로도 절차형 언어에 비하면 놀라운 발전이지만,상속은 새로운 차원의 기능이 추가된 것이다.상속을 활용하면 기존 클래스를 바탕으로새 클래스를 정의할 수 있다.따라서 클래스는 재사용하거나 확장 가능한 컴포넌트인 것이다.상속의 강력함을 최대한 잘 활용하기 위해서는상속에 관련된 구체적인 문법 뿐만 아니라상속을 최대한 활용하기 위해서는 상속과 관련된 고급 테크닉까지 알아야한다.상속을 이용한 클래스 구현현실에서 존재하는 대상의 대부분은 계층 구조를 가진다.프로그래밍에서도 이와 마찬가지로클래스를 수정하거나 다른 클래스를 바탕으로새 클래스를 정의할 때 이러한 관계를 분명히 볼 수 있다.코드에서 이러한 관계를 다루는 한 가지 방법은기존 클래스를 복사하여 ..

람다 함수들

람다 함수들 람다도 초보자에겐 생소한데람다 함수"들"? 이라고 하니 좀 더욱 더 생소할 것이다. 지금부터 람다에 대해서 간략하게 설명하겠다. 람다(lambda) 함수(람다 표현식 또는 간단히 람다라고도 함)를 보면초보 프로그래머에게 도움이 될 수 있도록 추가된C++11의 기능이 아니라고 의심할 수 있다.람다 함수는 겉보기에도 그런 의구심을 가질 수 있기 때문이다.람다 함수의 예제이다. [&count] (int x} {count += (x % 13 == 0);}  하지만 보이는 것 만큼 미스터리한 것은 아니며특히 함수를 사용하는 STL 알고리즘에서 유용한 서비스를 제공한다.  함수 포인터, 펑크터 그리고 람다 사용법 STL 알고리즘에 정보를 반영하는 세 가지 접근법을 사용한 예제를 살펴보자.우선 이 세가지..

안정된 인터페이스 만들기

클래스는 C++의 기본 추상화 단위다.클래스를 작성할 때추상화 원칙을 적용하여 인터페이스와 구현을 최대한 분리하는 것이 좋다.특히 데이터 멤버를 private로 지정하고게더와 세더를 제공하는 것이 바람직하다.인터페이스 클래스와 구현 클래스앞서 설명한 기준과 바람직한 설계 원칙을 적용하더라도C++언어와 추상화 원칙에 잘 맞지않는 부분이 있다.C++에서는 public 인터페이스와 private(또는 protected) 데이터 멤버 및 메서드를모두 클래스 정의에 작성하기 때문에클래스 내부 구현사항이 클라이언트에 어느 정도 노출될 수밖에 없다.그러므로 비 public 메서드나 데이터 멤버를 클래스에 추가할 때마다이 클래스를 사용하는 클라이언트 코드를 매번 다시 컴파일해야 하는 단점이 있다.프로젝트가 커질수록 이..

C++ 20 중첩 클래스

중첩 클래스클래스 정의에는 데이터 멤버와 멤버 함수 뿐만 아니라 중첩 클래스, 구조체, 타입 앨리어스(typedef), 열거 타입(enum)도 선언할 수 있다.클래스 안에서 선언한 모든 것은해당 클래스의 스코프로 제한된다.public으로 선언한 멤버를 클래스 외부에서 접근할 때는ClassName::과 같이 스코프 지정 연산자를 붙여야 한다.클래스 정의 안에서 다른 클래스를 정의할 수도 있다.예를 들어 SpreadsheetCell 클래스를Spreadsheet 클래스 안에서 접근할 수 있다.그러면 Spreadsheet 클래스의 일부분이 되기 때문에이름을 간단히 cell이라고 붙여도 된다.예를 들면 다음과 같다.export class Spreadsheet{ public : class Cell ..

이동 의미론으로 이동 처리하기

객체에 이동 의미론(move semantic)을 적용하려면이동 생성자와 이동 대입 연산자를 정의해야 한다.그러면 컴파일러는 원본 객체가 임시 객체로 되어있어서연산을 수행한 후 자동으로 제거되거나사용자가 명시적으로 std::move()를 호출하여 삭제될 때앞서 정의한 이동 생성자와 이동 대입 연산자를 이용한다.즉 메모리를 비롯한 리소스의 소유권을 다른 객체로 이동시킨다.이 과정은 멤버 변수에 대한 얕은 복제와 비슷하다.또한 할당된 메모리나 다른 리소스에 대한 소유권을전환함으로써 댕글링 포인터나 메모리 누수를 방지한다.이동 생성자와 이동 대입 연산자는 원본 객체에 있는데이터 멤버를 새 객체로 이동시키기 때문에그 후 원본 객체는 정상이긴 하나 미확정된 상태로 남게 된다.흔히 이러한 원본 객체의 데이터 멤버의 ..

포인터를 사용하는 이유 토막 정리

포인터를 왜 쓰는지 알면언제 써야할지 명확하게 알고 쓸 수 있다1. 포인터 변수에 함수 주소를 저장하고 이를 호출해 상황에 따라 다르게 작동하는 코드를 만들 수 있다거나ex) 함수 포인터, 델리게이트 등2. 크기가 큰 구조체나 클래스를 매개변수로 넘겨줄 때 값 복사로 넘겨주면 상당히 무거운 작업이 되므로 이에 대한 참조(주소)만 넘겨준다던가ex) const & 같이 넘겨주는 경우3. 동적 할당한 메모리를 포인터로 가리킬 수 있다거나ex) 동적 할당 메모리 관리1,3번의 활용상속구조를 이용해서 버추얼테이블을 효율적으로 활용하는 캐스팅2번으로 상속구조 클래스 내부의 함수 얕은 참조로 경량화 가능