Programming Tools/C++

[코드 중심 C++] - 접근제한자 private, protected, public, Friend 키워드, Static 키워드

LiDARian 2021. 5. 13. 23:43
반응형

1

클래스와 구조체의 근본적인 차이가 무엇일까.

은닉 기능의 차이다.

C++의 접근제한자 3가지 private, protected, public이 있다.

 

private로 선언하면 클래스 내부의 멤버 함수 또는 friend 함수만 클래스의 private 멤버에 접근할 수 있다.

 

protected로 선언하면 클래스 외부에서는 protected 멤버에 접근할 수 없다.

해당 클래스의 하위 클래스(상속)에서는 접근할 수 있다.

 

public으로 선언된 데이터 멤버와 메서드는 다른 클래스에서도 접근이 가능하다.

public 멤버는 . 연산자를 사용하여 접근한다.

 

2

friend 키워드를 통해 특정한 객체의 모든 멤버에 접근할 수 있다.

friend를 통해서 함수를 작성하면 그 함수는 클래스의 메서드로 인식되지 않는다. 그렇지만 private 멤버에 접근할 수 있게된다.

#include <iostream>
#include <string>

using namespace std;

class Student {
private:
	int studentId;
	string name;
public:
	Student(int studentId, string name): studentId(studentId), name(name) { }
	
	// friend 키워드를 이용해 다른 객체의 private 멤버인 name에 바로 접근 가능.
	friend Student operator +(const Student &student, const Student &other) {
		return Student(student.studentId, student.name + " & " + other.name);
	}
	// 아래와 같이 대체할 수 있다.
	// Student operator +(const Student &other) {
	// 	return Student(studentId, name + " & " + other.name);
	// }
	
	void showName() { cout << "name: " << name << '\n'; }
};

int main(void) {
	Student student(1, "Alex");
	Student result = student + student;
	result.showName();
}

// output
// Name: Alex & Alex

friend 키워드를 굳이 써야할까?

Student operator +(const Student &student, const Student &other) {
	return Student(student.studentId, student.name + " & " + other.name);
}

// error: ‘Student Student::operator+(const Student&, const Student&)’ must have either zero or one argument

operator 함수는 0 혹은 1개의 인자까지만 받을 수 있다.

 

3

아래와 같이 클래스 밖에 함수를 정의하여 가독성을 높일 수 있다.

#include <iostream>
#include <string>
using namespace std;
 
class Friend1 {
private :
    string name;
 
	//이렇게 자신의 private 멤버에 참조가 가능한 함수가 있다고 선언해주어야한다.
    friend void set_name(Friend1&, string);
};
 
// 클래스 밖에서 함수 정의
void set_name(Friend1& f, string s) {
    f.name = s;
    cout << f.name << "\n";
}
 
int main(void) {
    Friend1 f1;
 
    set_name(f1, "Alex");
 
    return 0;
}

 

 

4

friend 키워드를 클래스에 쓰면 이렇게 된다.

 

#include <iostream>
#include <string>
#include <ctime>


using namespace std;


class Time {
friend class Date; // Date 클래스에서 Time 클래스를 이용할 수 있음.
private:
	int hour, min, sec;
public:
	void setCurrentTime() {
		time_t currentTime = time(NULL);
		struct tm *p = localtime(&currentTime);
		hour = p->tm_hour;
		min = p->tm_min;
		sec = p->tm_sec;
	}
};


class Date {
private:
	int year, month, day;
public:
	Date(int year, int month, int day): year(year), month(month), day(day) { }
	void show(const Time &t) {
		cout << "지정된 날짜: " << year << "년 " << month << "월 " << day << "일" << '\n';
		cout << "현재 시간: " << t.hour << ":" << t.min << ":" << t.sec << '\n';
	}
};


int main(void) {
	Time time;
	time.setCurrentTime();
	Date date = Date(2021, 05, 13);
	date.show(time);
}

friend가 안되어있으면 Time클래스의 메서드로 Time클래스의 private영역에 들어가야하지만, friend class로 지정해주면서 Date클래스에서 직접 private 속성에 들어가게 해준다.

 

 

 

5

정적 멤버(Static Member)란 클래스에는 포함 되어 있는 멤버이지만 모든 객체가 공유하는 멤버. 그러므로 메모리 상에 오직 하나만 할당되어서 관리된다.

정적 멤버를 public으로 선언하면 모든 외부 클래스/함수에서 접근하여, 오직 하나의 멤버변수를 관리할 수 있다.

 

#include <iostream>
#include <string>


using namespace std;


class Person {
private:
	string name;
public:
	static int count;
	//객체가 하나 생길떄마다,(생성자가 사용될때마다.) count가 1 올라간다.
	Person(string name) : name(name) {
		count++;
	}
	

};

//여기에 Person class의 count를 선언하면 Person class의 모든 객체에서 참조가 가능해진다.
int Person::count = 0;

int main(void) {
	Person p1("Alex");
	Person p2("Bob");
	Person p3("Cert");
	cout << "사람의 수: " << Person::count << '\n';
}

// output
// 사람의 수: 3

참고

임시객체와 const사용에 관한 글

https://supark7.tistory.com/entry/19-%EC%9E%84%EC%8B%9C%EA%B0%9D%EC%B2%B4

const와 pointer

https://dydtjr1128.github.io/cpp/2020/01/08/Cpp-const.html

연산자 오버로딩과 friend 키워드

https://choryeonworkshop.tistory.com/130

https://thrillfighter.tistory.com/283

static 키워드

https://boycoding.tistory.com/169

반응형