반응형

접근 지정자

  • 멤버 데이터를 외부에서 직접 변경하면 잘못된 값을 가질 수 있으므로 멤버 함수를 통해서만 변경하도록

  • 멤버 함수를 통해서 인자의 유효성 여부도 조사 가능

  • 접근 지정자

    • private : 멤버 함수에서만 접근 할 수 있음

    • public : 멤버 함수가 아닌 함수에서도 접근 가능

  • struct vs class

    • struct : 접근 지정자 생략시 기본 접근자가 public

    • class : 접근 지정자 생략시 기본값이 private

struct Bike // struct -> class로 변경시 기본 접근자가 private 이므로 아래 private 생략 가능
{
private:
    int gear; // private 접근 지정자로 외부에서 직접 접근 불가

public:
    void changeGear(int n)
    {
        if( n > 0 ) // 잘못된 파라미터 체크
            gear = n;
    }
};

int main()
{
    Bike b;
    b.changeGear(-10); // 안전하게 멤버 함수를 통한 접근만 허용
}
  • Friend
    • 멤버 함수는 아니지만 private 멤버에 접근 가능

    • 멤버 함수로 만들수 없는 특정 상황에서 사용

    • getter, setter 함수 제공과의 차이점

      • getter : 모든 함수가 멤버 데이터에 접근할 수 있음

      • friend : 약속된 함수만 멤버 데이터에 접근 할 수 있음

class Bike
{
private:
    int gear;

public:
    void changeGear(int n) { if( n > 0 ) gear = n; }

    // friend 함수 지정으로 멤버 함수가 아니지만 private 변수에 접근 허용
    friend void fixBike(); 

    // friend 클래스 지정으로 AAA클래스 모든 멤버 함수에서 private 변수 접근 허용
    friend class AAA;
};

class AAA
{
};

void fixBike()
{
    Bike b;
    b.changeGear = 0;
}

int main()
{
    Bike b;
    b.changeGear(-10);
}

생성자( Constructor )

  • 모양

    • 클래스 이름과 동일

    • 리턴 타입 표기 X

    • 파라미터 선택적

    • 2개 이상 생성 가능

  • 특징

    • 객체를 생성하면 자동으로 생성자가 호출됨

    • 생성자가 없으면 객체 생성 불가

    • 사용자가 생성자를 정의하지 않으면 컴파일러가 기본 생성자(Default Constructor)를 생성함

    • 생성자를 1개 이상 정의 해놓은 상태라면 기본 생성자가 생성되지 않음
class Point
{
    int x, y;
public:
    Point() { x = 0; y = 0; } // 생성자 #1
    Point(int a, int b) { x = a, y = b; } // 생성자 #2
};

int main()
{
    Point p1; // 생성자 #1 호출
    Point p2(1, 2); // 생성자 #2 호출
    Point p3{ 1, 2 }; // 생성자 #2 호출

    Point p4[3]; // 생성자 #1 3회 호출
    Point p5[3] = { Point(1, 2) }; // 생성자 #2 1회 호출, 생성자 #1 2회 호출

    Point* p6; // 생성자 호출 안됨(Point 포인터 메모리만 할당)
    p6 = static_cast<Point*>(malloc(sizeof(Point))); // 생성자 호출 안됨(Point 사이즈 메모리 할당)
    p6 = new Point(1, 2); // 생성자 #2 호출

    delete p6;
}
  • 호출 순서
    • 객체를 구성하는 멤버의 생성자가 먼저 호출 되고, 객체 자신의 생성자가 호출됨
// 생성자 호출 순서

class Point
{
    int x, y;
public:
    Point() { x = 0; y = 0; }
    Point(int a, int b) { x = a, y = b; }
};

class Rect
{
    Point p1;
    Point p2;
public:
    Rect() { std::cout << "Rect()" << std::endl; }
};

int main()
{
    Rect r; // 생성자 호출 순서 : p1 -> p2 -> Rect
}
  • default

    • 컴파일러에게 default 생성자 생성을 위임하는 방법(기본 생성자 내부에서 할일이 없는 경우 default 사용 권장)
class Point
{
    int x, y;
public:
    Point() = default; // 기본 생성자 컴파일러 생성 위임(C++11, x,y 값이 0으로 초기화)
    Point() {} // 기본 생성자 직접 생성(x, y 값 초기화 안됨)
};

int main()
{
    Point p1{};
}

소멸자( Destructor )

  • 모양

    • ~클래스 이름()
    • 리턴 타입 표기 안함
    • 파라미터 사용 불가
    • 1개만 생성 가능
  • 특징
    • 객체가 파괴될때 소멸자가 호출됨
    • 객체가 자원을 할당한 경우 소멸자에서 자원 해지 필요
    • 사용자가 소멸자를 만들지 않으면 컴파일러가 생성함
class Point
{
    int x, y;
    int* buf;
public:
    Point() 
    {
        std::cout << "Point()" << std::endl;
        buf = new int[10];
    }
    ~Point()
    {
        delete[] buf;
        std::cout << "~Point()" << std::endl;
    }
};

int main()
{
    Point p;
}

초기화 리스트

  • 생성자의 ()뒤에 : 을 표기하고 멤버를 초기화 하는것

  • 특징

    • 대입이 아닌 초기화

  • 주의사항

    • 멤버가 놓인 순서대로 초기화됨(다른 멤버의 초기화 값을 대입시에 주의)

// 초기화 리스트를 이용한 초기화
class Point
{
    int x, y;
    const int c;
public:
    Point() : x(0), y(0), c(10) // 초기화 리스트
    {
        
    }
};

int main()
{
    Point p;
}

// 대입방법으로 초기화
class Point
{
    int x, y;
    const int c = 10;
public:
    Point()
    {
        x = 0;
        y = 0;
    }
};

int main()
{
    Point p;
}
  • 초기화 리스트가 반드시 필요한 경우

    • 객체가 상수 멤버나 참조 멤버를 가진 경우

    • 기본 생성자가 없는 객체를 멤버로 가진 경우

class Point
{
    int x, y = 0;
public:
    Point(int a, int b) : x(a), y(b) {} // 생성자 #2
};

class Rect
{
    Point p1; // 기본 생성자가 없는 Point
    Point p2; // 기본 생성자가 없는 Point

    const int c;
    int& radius;
public:
    Rect(int& r) : p1(0,0), p2(0,0), c(0), radius(r) // 초기화 리스트에서 생성자 #2로 초기화 지정
    {
    }
};

int main()
{
    int radius = 15;
    Rect rect{ radius };
}

위임 생성자(Delegate Constructor)

  • 하나의 생성자에서 다른 생성자를 호출하는 문법
  • 초기화 리스트 구문에서 다른 생성자를 호출
  • C++11 이상
// Point() 생성자 호출 시 Point(int a, int b)를 호출하고 싶을때

class Point
{
    int x, y;
public:
    Point() : Point(0, 0) // 위임 생성자
    {
        Point(0, 0); // 생성자 호출이 아닌 임시 객체 생성 X
    }
    Point(int a, int b) : x(a), y(b) {} // 생성자 #2
};

 

멤버를 초기화 하는 3가지 방법

  • 생성자의 블록 안에서 초기화 -> 대입(상수, 인자 가능)

  • 초기화 리스트 -> 초기화(상수, 인자 가능)

  • 멤버 변수 선언시 초기화 -> 초기화(상수만 가능)

// 1. 대입 초기화
class Point
{
    int x;
    int y;
public:
    Point(int a, int b)
    {
        x = 0; // 파라미터, 상수 모두 사용 가능
        y = 0;
    }
};

// 2. 초기화 리스트 
class Point
{
    int x;
    int y;
public:
    Point(int a, int b) : x(a), y(b) // 상수, 파라미터 모두 사용 가능
    {
    }
};

// 3. 멤버 변수 선언 초기화
class Point
{
    int x = 0; // 생성자에서 받은 파라미터는 활용 불가, 상수만 가능
    int y = 0;
public:
    Point(int a, int b)
    {
    }
};
반응형

'프로그래밍 언어 > C++' 카테고리의 다른 글

C++ static, const, this  (0) 2019.05.07
C++ 복사 생성자  (0) 2019.05.06
C++ OOP(Object Oriented Programming)  (0) 2019.05.06
C++ Explicit Casting  (0) 2019.05.06
C++ reference 변수  (0) 2019.05.06

+ Recent posts