C , C++

C++ 클래스 접근제어자 정리 및 사용예제 클래스에 대해 알아보자

coke-dev 2023. 7. 8.

C++은 객체 지향 프로그래밍 언어로, 클래스(class)를 사용하여 객체(object)를 정의하고 생성하는 것이 가능합니다. 클래스는 데이터와 해당 데이터를 처리하는 메서드의 집합으로 구성됩니다. 객체는 클래스의 인스턴스로, 클래스에서 정의된 속성과 메서드에 접근할 수 있는 실체입니다.

 

클래스 만드는 방법 예시

class ClassName {
    // 멤버 변수 (속성)
    // 멤버 함수 (메서드)
};

 

여기서 ClassName은 클래스의 이름을 나타내며, 클래스 정의 안에 멤버 변수와 멤버 함수를 추가할 수 있습니다.

멤버 변수는 클래스의 속성을 나타내며, 해당 클래스의 모든 인스턴스에 대해 동일한 변수가 각각 생성됩니다. 멤버 변수는 클래스 내에서 선언되며, 일반적으로 private, protected 또는 public으로 접근 제어 지시자를 사용하여 접근 범위를 설정할 수 있습니다.

멤버 함수는 클래스의 동작을 정의하는 함수입니다. 멤버 함수는 클래스 내에서 정의되며, 클래스의 객체에 의해 호출됩니다. 멤버 함수는 클래스 내의 멤버 변수에 접근할 수 있으며, 클래스의 상태를 변경하거나 클래스와 관련된 작업을 수행할 수 있습니다.

클래스의 인스턴스(객체)를 생성하기 위해서는 클래스 이름을 사용하여 변수를 선언해야 합니다.

 

클래스 인스턴스(객체)를 만드는 방법

ClassName objectName;

이렇게 객체를 생성하면 해당 클래스의 생성자(constructor)가 호출되어 초기화 작업을 수행합니다. 생성자는 클래스의 멤버 변수를 초기화하는 특수한 멤버 함수입니다. 생성자는 클래스 이름과 동일한 이름을 가지며, 객체가 생성될 때 자동으로 호출됩니다.

클래스는 객체 지향 프로그래밍의 주요 개념 중 하나로, 코드의 재사용성과 모듈화를 촉진합니다. 클래스를 사용하면 관련 데이터와 기능을 하나의 단위로 묶을 수 있으며, 객체 간의 상호작용을 표현하기에 용이합니다

 

 

클래스 접근제어자

 

클래스의 접근 제어자(access specifier)는 클래스의 멤버 변수와 멤버 함수의 접근 범위를 제어하는 데 사용됩니다. C++에서는 세 가지 접근 제어자가 제공됩니다. private, protected, public.

 

 

private

private 멤버 변수와 private 멤버 함수는 해당 클래스 내부에서만 접근할 수 있습니다.
클래스 외부에서는 private 멤버에 직접 접근할 수 없으며, public 인터페이스를 통해 접근해야 합니다.
클래스의 구현 세부 정보를 숨기고, 캡슐화를 지원하는 데 사용됩니다.

 

사용예시

class MyClass {
private:
    int privateData;  // private 데이터 멤버

    void privateMethod() {
        // private 도우미 메서드
    }

public:
    void publicMethod() {
        // public 메서드에서 private 멤버에 접근 가능
        privateData = 10;
        privateMethod();
    }
};

 

위의 예시에서 privateData와 privateMethod()는 private로 선언되었습니다. 이들은 클래스 외부에서 직접 접근할 수 없으며, 오직 publicMethod()와 같은 공개(public) 멤버를 통해서만 접근할 수 있습니다.

주의할 점은 private 멤버는 동일한 클래스의 다른 멤버들 간에는 접근이 가능하다는 것입니다. 따라서 publicMethod()에서는 privateData에 접근하여 값을 설정하고 privateMethod()를 호출할 수 있습니다.

클래스의 멤버 변수는 보통 private로 선언하고, 필요에 따라 public으로 접근할 수 있는 메서드를 통해 간접적으로 접근하는 것이 일반적인 설계 원칙입니다. 이렇게 하면 클래스의 내부 구현을 캡슐화하여 외부에서 직접적인 접근을 제한하고, 클래스의 일관성과 안정성을 유지할 수 있습니다.

 

 

protected

protected 멤버 변수와 protected 멤버 함수는 해당 클래스 내부와 파생 클래스(derived class)에서 접근할 수 있습니다.
클래스 외부에서는 protected 멤버에 직접 접근할 수 없으며, public 인터페이스를 통해 접근해야 합니다.
파생 클래스에서 기반 클래스의 protected 멤버에 접근하여 상속된 멤버를 사용할 수 있도록 지원합니다.

 

사용예시

class BaseClass {
protected:
    int protectedData;  // protected 데이터 멤버

    void protectedMethod() {
        // protected 도우미 메서드
    }
};

class DerivedClass : public BaseClass {
public:
    void accessProtected() {
        protectedData = 10;       // protected 멤버에 접근 가능
        protectedMethod();        // protected 메서드 호출 가능
    }
};

 

위의 예시에서 BaseClass는 protectedData와 protectedMethod()를 protected로 선언했습니다. 이들은 BaseClass와 DerivedClass에서 접근 가능한 멤버입니다.

DerivedClass에서 accessProtected() 함수를 통해 protectedData에 접근하고 protectedMethod()를 호출할 수 있습니다. 이는 DerivedClass가 BaseClass를 상속받았기 때문에 가능한 동작입니다.

주의할 점은 protected 멤버는 파생 클래스에서 직접 접근할 수 있지만, 일반적인 상황에서는 외부에서 직접 접근하는 것을 피하는 것이 좋습니다. 대신에 파생 클래스에서 protected 멤버에 접근할 수 있는 공개(public) 메서드를 제공하는 것이 일반적인 설계 원칙입니다. 이렇게 함으로써 클래스의 내부 구현을 캡슐화하고, 파생 클래스에서만 필요한 기능에 접근할 수 있도록 제한할 수 있습니다.

 

public

public 멤버 변수와 public 멤버 함수는 클래스 외부에서도 접근할 수 있습니다.
클래스의 인터페이스를 정의하고, 객체가 클래스의 기능을 사용할 수 있도록 합니다.
객체를 생성한 후, public 멤버 함수를 통해 클래스의 기능을 호출하거나 public 멤버 변수에 접근할 수 있습니다.

 

이러한 접근 제어자는 클래스의 멤버 변수와 멤버 함수를 적절하게 보호하고, 정보 은닉과 캡슐화를 지원하여 클래스의 내부 구현을 감춥니다. 이는 코드의 안정성을 높이고 외부로부터의 부적절한 접근을 방지하는 데 도움이 됩니다.

클래스의 접근 제어자는 기본적으로 private입니다. 따라서 멤버 변수와 멤버 함수를 선언할 때 별도의 접근 제어자를 지정하지 않으면 private으로 간주됩니다. 개발자는 접근 제어자를 명시적으로 지정하여 클래스의 멤버에 적절한 접근 권한을 부여할 수 있습니다.

 

사용예시

class MyClass {
public:
    int publicData;  // public 데이터 멤버

    void publicMethod() {
        // public 메서드
    }
};

위의 예시에서 publicData와 publicMethod()는 public으로 선언되었습니다. 이들은 클래스 외부에서 직접적으로 접근할 수 있으며, 다른 클래스나 함수에서도 사용할 수 있습니다.

 

외부에서 public 멤버함수 사용예시

MyClass obj;
obj.publicData = 10;     // public 데이터 멤버에 접근 및 수정
obj.publicMethod();

클래스의 객체 obj를 생성하고, 이를 통해 publicData 멤버에 접근하고 수정할 수 있습니다. 또한 publicMethod()를 호출할 수도 있습니다.

public 멤버는 클래스 외부에서 직접적으로 접근 가능하기 때문에, 주의가 필요합니다. 클래스의 일부 상태나 동작을 외부에 노출하고자 할 때 사용되지만, 모든 멤버를 public으로 선언하는 것은 좋은 설계 원칙이 아닐 수 있습니다. 정보 은닉과 캡슐화를 통해 클래스의 내부 구현을 캡슐화하고, 외부에서는 필요한 기능에 대한 공개(public) 인터페이스를 제공하는 것이 일반적으로 권장되는 방식입니다.

 

 

 

클래스 접근제어자 사용하는 main함수 예시

 

#include <iostream>

class MyBaseClass {
protected:
    int protectedData;

public:
    void setProtectedData(int value) {
        protectedData = value;
    }

    int getProtectedData() {
        return protectedData;
    }
};

class MyDerivedClass : public MyBaseClass {
private:
    int privateData;

public:
    void setPrivateData(int value) {
        privateData = value;
    }

    int getPrivateData() {
        return privateData;
    }
};

int main() {
    MyDerivedClass obj;
    obj.setProtectedData(5);
    int protectedData = obj.getProtectedData();
    std::cout << "Protected data: " << protectedData << std::endl;

    obj.setPrivateData(10);
    int privateData = obj.getPrivateData();
    std::cout << "Private data: " << privateData << std::endl;

    return 0;
}

 

위의 예시에서 MyBaseClass는 protectedData라는 protected 멤버를 가지고 있습니다. MyDerivedClass는 privateData라는 private 멤버를 추가로 가지며, protectedData에 대한 접근도 가능합니다.

main 함수에서는 MyDerivedClass의 객체 obj를 생성하고, 
setProtectedData()와 getProtectedData() 함수를 사용하여 protectedData에 접근합니다. 
또한 setPrivateData()와 getPrivateData() 함수를 사용하여 privateData에 접근합니다.

 

출력결과

Protected data: 5
Private data: 10

 

이 예시에서 main 함수는 MyDerivedClass를 통해 protectedData와 privateData에 접근합니다. protectedData는 상속받은 멤버이므로 MyDerivedClass에서 직접 접근 가능하며, privateData는 MyDerivedClass의 private 멤버로서 해당 클래스 내부에서만 접근 가능합니다.

댓글

💲 추천 글