이건..

클래스의 기본 생성자, 소멸자, 복사 생성자, 복사 대입 연산자는

자동으로 생성될 수 있으니 체크해보자는건데..


뭐..

class ABC

{

private:

int m_iNum;

public:

ABC();                                        // 생성자

ABC(int iNum){ m_iNum = iNum };    // 복사 대입 연산

~ABC();                                       // 소멸자

}

클래스는 기본적으로 생성자 소멸자가 생성이 된다.

int a;

라고 선언 했을때 상황에 따라 초기화가 될때도 있고 되지 않을떄도 있다.


이거 예전에 어떤 상황인지 는 모르겠지만 이거 때문에 값하나 틀어져서

설마설마 하면서 초기화 했더니 됬던 일이 있었다.

그게 뭔지는 모르겠지만 그뒤론 항상 선언+초기화 를 하게 됬심..

const : 어떤 값이 변하지 않는 상수화를 할 때 앞에 붙여주는 키워드 이다.


char *p = abc;                            // 비상수 포인터, 비상수 데이터

const char*p = abc;                    // 비상수 포인터, 상    수 데이터

char * const p = abc;                  // 상    수 포인터, 비상수 데이터

const char * const p = abc;         // 상    수 포인터, 상    수 데이터

const 키워드가 *의 왼쪽에 있으면 포인터가 가르키는 대상이 상수이며 오른쪽에 있으면

포인터 자체가 상수이며 양쪽 다 있으면 둘다 상수 이다.


그리고

void a1( const abc *pw );    // a1은 상수 abc객체에 대한 포인터를 매개변수로 취한다

void a2( abc const *pw );    // 위와 동일

함수의 반환값을 상수로 정해주면 사용자측의 에러를 줄이는 효과가 있다.

const ABC operator* ( const ABC& aa, const ABC& bb ); 이렇게 정의해 두면

ABC a,b,c;

a * b가 c와 같은지 알려고 작성하던중 실수로

if( a * b  = c ); 이렇게 대입연산을 하게 될 경우를 방지 할 수 있다.


◎ 비트수준 상수성

어떤 멤버 함수가 그 객체에 어떤 데이터 멤버도 건드리지 않아야 한다. 그 객체를 구성하는 비트들 중 어떤 것도 바뀌면 안된다는 것이다. C++에서 사용하는 상수 수준이다.

◎ 논리적 상수성

상수 멤버 함수라고 해서 객체의 한 비트도 수정 할 수 없다는 것이 아니라 일부 몇 비트정도는 바꿀수 있되 그것을 사용자측에서 알아채지 못하게만 하면 상수 멤버 자격이 있다는 것이다.

mutable 키워드를 이용하면 비트 수준의 상수성을 풀어 줄 수 있다.



< const를 붙여 선언하면 컴파일러가 사용상의 에러를 잡아내는데 도움을 준다. >

< const는 어떤 유효범위에 있는 객체에도 붙을수 있다. 함수 매개변수, 반환타입, 멤버함수  >

< 컴파일러 쪽에서 보면 비트수준 상수성을 지켜야 하지만, 논리적인 상수성을 사용해서 작성해야 한다 >

< 상수 멤버 및 비상수 멤버가 기능적으로 서로 똑같게 구현 되어 있을 경우 코드 중복을 피하는 것이

좋다. 이때 비상수 버전이 상수버전을 호출하도록 만들면 된다 >


가급적 선행처리가 보다 컴파일러를 더 가까이 하자..

#define ABC 100

전처리기에 의해 ABC는 100으로 치환 된다.

에러발생시 100만 남게되고 이 파일이 자신이 작성한것이 아니라면 어디서 나온 값인지 알아보기 힘

들게 된다. 전처리기에 의해 정의되므로 컴파일러의 기호 테이블에 들어가지 않기 때문이다. 

그리고 어떤 형태에서도 캡슐화 혜택을 받을수 없다.


그래서 #define 대신 const를 사용한다.

const int abc = 100;

포인터의 경우 포인터가 가르키는 값까지 상수로 선언해 준다

const char* const name = "hi";

const가 두번 들어간다.


글래스 상수를 정의하는 경우, 어떤 상수의 유효범위를 클래스로 한정하고자 할때 그 상수를 멤버로 만

들어야 하는데. 그 상수의 사본 개수가 한개를 넘지 못하게 하고 싶다면 정적(static)멤버로 만들어야 한다.

class ABC

{

private:

static const int num = 2;    // 상수 선언

int ret[num];    // 상수를 사용 하는 부분

};

만약 #define매크로 함수를 사용하게 되면 유효 범위도 없고 컴파일이 끝날때까지 유지된다는 문제가 있다. 하지만 위와같이 클래스 내부에서 정적 클래스 상수로 선언하게 되면 클래스의 캡슐화에도 용이하다. static 멤버는 초기화를 시켜줘야 한다

const int ABC::num = 2;


하지만 이 경우엔 컴파일 과정중 정적클래스 상수의 값이 필요할때 문제가 발생한다. 정적 클래스 상수에 대한 값이 초기화 되지 않았기 때문이다. 이를 해결하기 위한 방법으로 enum을 사용 한다.

class ABC

{

private:

enum{ num = 2 };    // enum을 사용하여 num을 2에 대한 기호식으로 만듬

};

enum은 const보다 define에 가깝다. const의 주소를 알아내는것은 가능하지만 enum의 주소를 알아내는것은 불법이며 define의 주소를 얻어 내는것 또한 그러하다. 본인이 선언한 정수형 상수를 다른 사람이 접근하는 것을 막으려 한다면 enum을 사용 하는 것이 좋다. 그리고 enum은 define과 마찬가지고 어떤 형태의 쓸데없는 메모리 할당도 저지르지 않는다.


그리고 #define의 가장 큰 오류는 매크로 함수이다

#define CALL_WITH_MAX(a, b)    f( (a)>(b) ? (a):(b) )

이런식의 매크로는

#define CALL_WITH_MAX(a, b)  ((a)>(b)?(a):(b))

int main()

{

int a = 5, b = 0;

int result = 0;


result = CALL_WITH_MAX(++a,b);


printf("%d", a);    // a가 2번증가한다

printf("%d", b);

printf("%d", result);

a = 5, b = 0;

result = CALL_WITH_MAX(++a,b+10);

printf("%d", a);    // a가 1번 증가한다

printF("%d", b);

printF("%d", result);

}

이것처럼 비교를 통해 처리한 결과가 어떤것이냐에 따라 달라진다.

이를 대체하기 위해 인라인 함수에 대한 템플릿을 사용한다. 이 함수는 기본의 매크로 함수의 효유을

그대로 유지함은 물론 정규 함수의 모든 동작 방식 및 타입의 안정성까지 취할 수  있다.

template<typename T>

inline int MAX( const T&, const T& b )    // T의 정확한 자료형을 모르기때문에 매개변수로 상수객체                   

{                                                            에 대한 참조자를 쓴다

return a > b ? a : b;

}

이 함수는 템플릿 이기 때문에 동일 계열 함수군을 만들어 낸다. 동일한 타입의 두 객체 두개를 인자로

받고 둘 중 큰 값을 리턴하는 구조다. 그리고 MAX는 함수기 때문에 유효 범위와 접근 규칙을 그대로따른다. 이것은 클래스 내부의 함수, 클래스 매서드로 만들어도 전혀 이상하지 않다.


#define 을 대신하여 더욱 활용가치가 높은 const, enum. inline 키워드를 사용하여 전처리기 활용을 

많이 줄일 수 있다.



< 단순한 상수를 쓸때는 #define 보단 const 또는 enum을 우선으로 생각하자 >

< 함수처럼 쓰이는 매크로를 만드려면 #define 매크로 보다 inline함수를 우선 생각 하자 >

C++은 다중 패러다임 프로그래밍 언어 라고도 불린다.

절차적 프로그래밍을 기본으로 하여 객체지향, 함수식, 일반화 프로그래밍을 포함하여 메타 프로그래밍 개념까지 지원 하고 있다.


연합체란

1. C : 블록, 문장, 선행 처리자, 기본제공 데이터 타입, 배열, 포인터 등등 모든것이 C에서 왔다.

2. 객체지향 개념의 C++ : 클래스를 쓰는 C에 대한 모든것 클래스, 캡슐화 ,상속, 다형, 가상함수

3. 템플릿 C++

4. STL : 템플릿 라이브러리 컨테이너, 반복자, 알고리즘, 함수객체가 있으며 사용 규약에 따라 사용하면된다.


C++은 한가지 프로그래밍 규칙 아래 뭉친 통합언어가 아닌 위이 네가지 언어들의 연합체이며 각각의 언어가 자신만의 규칙을 가지고 있다.

C++을 사용한 효과적인 프로그래밍 규칙은 경우에 따라 달라진다. 그 경우는 C++의 어떤 부분을 사용하느냐 이다.



« PREV : 1 : 2 : 3 : NEXT »