멤버함수와 클래스 활용

yu-podong·2021년 5월 20일
0

CPP

목록 보기
9/9
post-thumbnail

정적멤버


클래스의 멤버

static 멤버

프로그램이 시작할 때 생성되고, 클래스 당 하나만 생성된다. 그래서 클래스 멤버라고 불린다.
중요한 것은, 클래스의 모든 객체들이 공유하여 사용하는 멤버이다.

  1. 정적 멤버 변수
    : 같은 객체들 사이에 공유되는 멤버 변수이고, 일반 멤버처럼 접근 가능하다.
      단 class-name::staticMemName으로 접근해야 한다.
  2. 정적 멤버 함수
    : 객체 없이 호출할 수 있는 멤버 함수이고, 접근 방식은 2가지이다.
      - 일반 멤버함수처럼 접근 : object-name->function, object-name.function
      - 클래스 이름으로 접근 : class-name::function
    가장 중요한 것은 this포인터가 존재하지 않는다.
class student {
	public: 
    	int stdNum;
        static int stdCount;		// 전역 멤버 변수
        static void PrintStdCount();	// 전역 멤버 함수
}
// static 변수 공간 할당 (프로그램 전역 공간에 생성해야함)
int student::stdCount =1 ;

// 전역 함수 안에서는 일반 멤버에 접근할 수 없음 (어떤 객체의 멤버인지 몰라서)
void student::PrintStdCount() {
	// do something...
}

프로그램 시작 시, 멤버가 생성되며 객체가 생기기 전에도 이미 존재하는 멤버이다.
static멤버가 사용된 클래스의 객체가 사라져도 여전히 존재한다.
프로그램과 생성을 같이하기 때문에, 프로그램이 종료될 때 함께 소멸한다.

non-static 멤버

객체가 생성될 때 함께 생성되고, 객체마다 객체 내에 생성된다.
그래서 인스턴스 멤버라고 불린다.

static 멤버 특징

  1. 객체가 만들어지지 않은 상태에서도 사용 가능하다.
  2. 일반 멤버에 접근할 수 없다. (역은 성립)
    단, 해당 함수 안에서 어떤 객체의 것인지 지정하여 일반 멤버를 사용하면, 접근 가능하다.
void student::PrintStdCount() {
	student st1("",0);
    std.stdNum = 202105020;
}

const 객체와 const 멤버함수


const 객체

멤버 변수의 값을 변경할 수 없으므로, const 객체 선언 후에는 대입을 진행할 수 없다.
그리고 멤버 변수의 값을 변경하는 멤버 함수를 호출할 수 없다.
=> 즉, const멤버 함수만 호출할 수 있다.

Stack s1(4);
const Stack st2;	// 디폴트 생성자로 초기화 진행
s2 = s1; 		// (X)

실질적으로 멤버 변수를 변경하지 않는 일반 멤버 함수일지라도, 값을 변경하지 않는다는 것을 증명하는 const를 부여받아야만 const객체가 호출할 수 있다.

const 멤버 함수

객체의 값을 변경하지 않기로 약속하는 멤버 함수이고, 이는 "이 함수에서 멤버 변수의 값을 변경하지 않으므로, const 객체가 이 멤버함수를 호출해도 안전하다."는 의미이다.

지정방법은 함수의 선언 & 정의 모두 const 키워드를 지정한다.

// 선언부
class ClassName {
	멤버함수 선언 const;
}
// 구현부
returnType className::function() const {
	// 멤버 변수 값 변경 X
    	// 일반 멤버 함수 호출 X
}

해당 함수 안에서는 멤버 변수의 값을 변경 & 다른 일반 멤버 함수 호출이 불가능하다.

여러가지 객체의 생성방법


객체 배열 & 포인터의 생성 및 사용

객체배열

우리가 배운 배열과 똑같은 방식으로 선언한다. ( 2차원 배열또한 same )
객체 배열 생성할 때 원소의 값을 따로 지정하지 않으면 항상 디폴트 생성자로 초기화된다.

// 디폴트 생성자로 초기화
student stdArr[3]; 
// 배열의 원소는 `생성자`를 나열하여 지정
student stdArr2[] = {student(10,"std1"), student(20,"std2"),student(30,"std3")}

만약, 클래스 내에 직접 생성자를 만들었는데 디폴트 생성자가 없다면 error 발생!

class student{
	private:
    		int stdNum;
	public:
    		student(int stdNum);
		//student();
}
int stdArr3[];	// 디폴트 생성자가 존재하지 않아서 error 발생

if, 동적 메모리로 배열을 할당 & 해제하고 싶다면

// 동적 객체 배열은 항상 디폴트 생성자로 초기화
// 고로, 해당 클래스에 `디폴트 생성자가 없다면` 동적 객체 배열 생성 불가능
className *pointerName = new className[array_size];

delete[] pointerName;

if. 포인터 배열로 사용하고 싶다면

// 배열의 원소 : student객체의 주소 ( student의 pointer )
student* stdArr[2] = { new student(10,"std1"), new student(20,"std2") };

for(int i = 0; i < 2; i++) {
	delete stdArr[i];
}

객체 포인터

우리가 배운 포인터와 동일한 방식으로 선언되고 사용된다.
객체 포인터로 멤버에 접근할 때는 객체 포인터->멤버 를 작성한다.

student std1;
std1.stdNum =202105020;

student *std_pointer = &std1;


if, 동적 메모리로 할당 & 해제하고 싶다면

className.pointerName = new className;		 // 디폴트 생성자 사용
className.pointerName = new className(매개 변수); // 매개변수가 있는 생성자 사용

delete pointerName;

0개의 댓글