ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 열혈강의 C++(잊어버린 부분 정리 1)
    @ 16. 1 ~ 17. 1/C++ 2014. 4. 6. 23:45

    1. 배열의 선언과정에서는 호출할 생성자를 별도로 명시하지 못한다.(생성자에 인자를 전달하지 못한다)

    SoSimple* ptrArr=new SoSimple[10];

    위의 형태로 배열이 생성되려면 다음 형태의 생성자가 반드시 정의되어야 한다.

    SoSimple() { . . .}

    그리고 일일이 초기화의 과정을 별도로 거쳐야 한다.

     

    2. 멤버 이니셜라이저에서는 this포인터를 사용할 수 없다.

     

    3. 복사생성자의 매개변수 선언에서 const는 필수가 아니다 그러나 참조형의 선언을 의미하는 &는 반드시 삽입해야한다.

     

    4. 복사생성자의 호출시점

      1) 기존에 생성된 객체를 이용해서 새로운 객체를 초기화하는 경우

      2) call - by - value방식의 함수호출 과정에서 객체를 인자로 전달하는 경우

      3) 객체를 반환하되, 참조형으로 반환하지 않는 경우

    이들 모두의 공통점은 "객체를 새로 생성해야한다. 단, 생성과 동시에 동일한 자료형의 객체로 초기화해야한다"

     

    5. 객체에 const 선언이 붙게되면 이 객체를 대상으로는 const 멤버함수만 호출이 가능하다.

    void SimpleFunc() { .... }

    void SimpleFunc() const { .... }

    이렇게 오버로딩도 된다.

     

    6. friend는 클래스 뿐만 아니라 전역함수, 클래스의 멤버함수를 대상으로도 선언이 가능하며

    선언된 함수는 자신이 선언된 클래스의 private영역에 접근이 가능하다.

     

    7-1. 전역변수에 선언된 static의 의미

      - 선언된 파일 내에서만 참조를 허용하겠다는 의미

    7-2. 함수 내에 선언된 static의 의미

      - 한번만 초기화되고, 지역변수와 달리 함수를 빠져나가도 소멸되지 않는다.

    7-3. static 멤버변수(클래스 변수)

      - 일반적인 멤버변수와 달리 클래스당 하나씩만 생성(객체가 생성될때 마다 함께 생성되어 객체별로 유지되는 변수가 아니라는 말)

      - 클래스별로 허용하는 객체가 구분되어 다른영역에서 잘못 접근하는 일이 없다.(클래스의 이름 또는 객체의 이름을 통해서는 어디서든 접근이 가능하다)

    7-4. static 멤버함수

      - 선언된 클래스의 모든 객체가 공유한다.

      - public으로 선언되면 클래스의 이름을 이용해서 호출이 가능하다.

      - 객체의 멤버로 존재하는 것이 아니다.

         * 즉, static 멤버함수 내에서는 static 멤버변수와 static 멤버함수만 호출이 가능하다

     

    8. 상속받은 클래스의 생성자는 상속해준 클래스의 멤버까지 초기화에 책임을 져야한다.

    왜냐면 상속받은 클래스의 객체가 생성되면 그 객체 안에는 상속해준 클래스의 멤버까지 존재하므로..

    그래서 상속받은 생성자는 상속해준 생성자를 호출하는 형태로 클래스의 멤버를 초기화 하는 것이 좋다.

    생성자(int a, int b, int c) : 상속해준클래스(a, b)

    이니셜라이저로 a,b의 인자를 전달하여 클래스의 생성자를 호출해준다.

    * 생성자 호출을 명시하지 않으면 void 생성자가(디폴트) 호출된다.

     

    9. 자식, 부모클래스의 생성, 소멸순서

    생성                            소멸

    부모-> 자식 -> 자식 -> 부모

     

    10. 상속은 is a 관계 일종의 ~ 이다로 표현이 되어야 한다. 아니라면 적절한 상속이 아니다.

    무선 전화기 is a 전화기

    노트북 is a 컴퓨터

    하지만 has - a의 관계도 있다. 즉, 소유

    경찰 has a 총 근데..

    되도록이면(대부분)

    경찰 클래스에서 총 클래스를 상속하는 것이 아니라, 멤버변수로 총 객체를 선언해서 사용하는게 낫다.

     

    11. A형 포인터 변수는 A 객체 또는 A를 직접 혹은 간접적으로 상속하는 모든 객체를 가리킬 수 있다(객체의 주소값을 저장할 수 있다)

    그래서 A* LIST[배열]에 상속하는 B, C가 저장이 된다는 것

     

    12. 함수 오버로딩은 매개변수의 인자를 틀리게 해서 이름과 반환값이 같은 함수를 말하며

    오버라이딩은 상속의 개념에서 부모클래스에서 작성된 함수는 동일한 이름과 형태의 자식 클래스의 함수에 가려진다.

    만약 동일한 형태가 아니라 매개변수의 자료형 및 개수가 다르면 오버로딩이 되어 전달되는 인자에 따라서 호출되는 함수가 결정된다.

     

    13. 포인터의 연산의 가능성 여부를 판단할떄 포인터의 자료형을 기준으로 판단하지 실제 가리키는 객체의 자료형을 기준으로 판단하지 않는다.

    부모* ptr=new 자식;

    자식->함수(자식내 멤버함수) // 컴파일 에러

    즉 부모* ptr은 부모멤버함수만 가능..

     

    부모* ptr=new 자식;

    자식* pptr=ptr(부모) // 컴파일 에러

    즉 부모 ptr은 부모형 포인터이니까 가리키는 대상이 부모일수도 있는것이므로 에러

    (간단하게 상속주는것이 상속받는것 아래로 못들어감. 아래도 다 에러..)

    1)

    자식* ptr = new 자식

    부모 *ptr = ptr(자식)  (가능)

    부모* ptr = new 부모

    자식 *ptr = ptr(부모)  (에러)

     

    2)

    자식* ptr = new 부모 (에러)

    부모* ptr = new 자식 (가능)

     

    14. 가상함수로 선언되면 함수호출 시 포인터의 자료형을 기반으로 호출대상을 결정하지 않고 포인터 변수가 실제로 가르키는 객체를 참조하여 호출한다.

     

    15. 동일한 포인터 변수이나 실행결과가 다른것은 객체의 자료형이(가르키는 객체가) 다르기 떄문이다 이것이 c++에서의 다형성을 나타낸다.

     

    16. 소멸자에 virtual 선언을 하는 이유는

    상속하는 부분에서 포인터 변수의 자료형에 상관하여 소멸자가 호출되버리는 경우가 있기 때문이다

    부모* ptr = new 자식

    delete 부모

    를 해버리면 부모의 소멸자만 호출된다(이유는 포인터 변수는 자료형을 따르기 때문에..)

    그래서 자식부분에서 new가 되어있다면 메모리 누수로 이어진다.

    해결책은 부모의 소멸자에 virtual 선언을 하여 가르키는 객체의 소멸자가 실행이 되도록 한다.

    (자식 소멸자가 단계별로 내려가서 부모 소멸자까지 실행하게 된다.)

     

Designed by Tistory.