1.1 클래스(Class)와 정보은닉
보안성 이라고 할 수 있다.1.2 정보은닉의 구현
< 맴버변수가 public 키워드로 정의되어있는경우 >
#include <iostream>
using namespace std;
class Student{
public:
char *name;
int age;
};
int main(void){
Student s1;
s1.name = "kim";
s1.age = 10;
cout<<s1.name<<endl;
cout<<s1.age<<endl;
return 0;
}
➡️ 이러한 경우, 어디서든 name 이나 age 같은 데이터에 접근할 수 있게 된다. 데이터의 노출뿐만 아니라 조작까지 가능하므로 보안에 굉장히 취약하다.
class Student{
private:
char *name;
int age;
public:
void getName() const{
cout<<name<<endl;
}
void getAge() const{
cout<<age<<endl;
}
};
Student 클래스의 맴버변수들을 private 키워드로 제한했다. 이러면 main 함수에서의 호출이 제한된다. 하지만 때에 따라서 맴버변수를 호출해야되는 경우가 있지 않나? 그래서 public 스페이스에 getName()과 getAge() 함수를 선언해 맴버변수에 접근할 수 있도록 하였다.
📢그런데 기존에 보던 함수랑 조금 다른 점이 있다. 바로 const 키워드이다. private 스페이스에 선언된 맴버변수에 저장된 값을 변경하지 않겠다 를 명시한다.
private 필드에 선언함으로써 정보를 보호하고 필요한 경우 public필드에 정의된 const 함수로 해당 맴버에 접근할 수 있다.1.3 생성자(Constructor)
생성자가 없는 경우 ) 객체( Class )를 초기화할 때 아래와 같은 방법을 사용했다.class TwoNumb{
private:
int x;
int y;
public:
void initNum(int a, int b){
x = a, y = b;
}
void printNum()const{
cout<<"x: "<<x<<" y: "<<y<<endl;
}
};
int main(void){
TwoNumb ab;
ab.initNum(1, 3);
ab.printNum();
return 0;
}
main에서 객체를 생성하고 이를 초기화 해줄 함수 init___를 호출해 초기화하였다. 이러한 번거로움을 피하기 위해 생성자 함수를 정의하여 객체를 생성하는 동시에 초기화까지 해보자.class TwoNumb{
private:
int x;
int y;
public:
TwoNumb(int a, int b){
x = a, y = b;
}
void printNum()const{
cout<<"x: "<<x<<" y: "<<y<<endl;
}
};
int main(void){
TwoNumb ab(1,3);
ab.printNum();
return 0;
}
➡️ 이렇게 선언과 동시에 객체를 초기화할 수 있게 되었다. 생성자의 특징 몇가지를 살펴보자.
1.3.1 생성자(Constructor)의 오버로딩
생성자 도 반환형 은 없지만 엄연한 함수이므로 오버로딩이 가능하다. TwoNumb(int a, int b){
x = a, y = b;
}
TwoNumb(int a){
x = a;
y = 0;
}
TwoNumb(){
x = 0;
y = 0;
}
1.3.2 생성자(Constructor)와 이니셜라이저
이니셜라이저(Initializer) 란 생성자가 호출되는 동시에 맴버변수를 초기화할 수 있는 키워드이다. 생성자 함수 내부에서 초기화하는 방식보다 속도가 빠르다! TwoNumb(int a, int b)
: x(a), y(b)
{
}
이니셜라이저를 활용하여 클래스로 생성된 맴버변수도 초기화할 수 있다.class Point{
private:
int xpos;
int ypos;
public:
Point(int x, int y)
:xpos(x), ypos(y)
{
}
};
class Straight{
private:
Point posOne;
Point posTwo;
public:
Straight(const int &x1, const int &y1, const int &x2, const int &y2)
:posOne(x1, y1), posTwo(x2,y2)
{
}
};
Fruitsale.cpp 예제에서 const 변수는 생성자함수나 다른 함수를 통해 초기화할 수 없었다. 하지만 이니셜라이저를 사용하면 가능하다!class Point{
private:
int xpos;
int ypos;
public:
Point(int x, int y)
:xpos(x), ypos(y)
{
}
};
class Straight{
private:
const int posz;
Point posOne;
Point posTwo;
public:
Straight(const int &x1, const int &y1, const int &x2, const int &y2, int a = 0)
:posOne(x1, y1), posTwo(x2,y2), posz(a)
{
}
};
📢생성자 함수 선언부에 보면 int a = 0 으로 선언된 매개변수가 있다.
특정 arguments가 전달되지 않았을 때를 보완하기 위한 default값 지정이다. main 함수에서 int a 에 대한 arguments를 전달하지 않아도 생성자 함수에서 자동으로 0 으로 초기화가 가능하다.
2.1
this키워드의 사용
this 키워드는 객체 자신을 가르킨다.this 키워드의 쓰임을 몇가지 살펴보자#include <iostream>
using namespace std;
class Point{
private:
int xpos;
int ypos;
public:
Point(int xpos, int ypos){
this->xpos = xpos;
this->ypos = ypos;
}
void printPos() const{
cout<<"xpos: "<<this->xpos<<" ypos: "<<this->ypos<<endl;
}
};
int main(void){
Point p1(10, 50);
p1.printPos();
return 0;
}
👉 line 9 의 생성자 함수 처럼 매개변수 명과 arguments의 이름이 같을 때 이를 구분하기 위해 this 키워드를 사용할 수 있다.
👉 생성자 함수 부분을 해석해보자면 this(Point 객체)의 맴버변수 xpos에 arguments 로 전달받은 값을 대입하라 정도로 할 수 있을 것이다.
#include <iostream>
using namespace std;
class Whiteboard{
private:
int number;
public:
Whiteboard(int x)
:number(x)
{}
Whiteboard& Adder(int x){
number += x;
return *this;
}
Whiteboard& showboard(){
cout<<"number: "<<number<<endl;
return *this;
}
};
int main(void){
Whiteboard wb(0);
wb.Adder(1).showboard().Adder(50).showboard();
return 0;
}
👉 main 함수 내부 코드를 보면
1. Whiteboard 클래스 객체 wb 를 생성
2. wb 객체의 함수(반환형이 Whiteboard의 주소인) Adder 실행
3. 반환형이 객체의 주소값이므로 '.(dot)' 연산자를 사용해 wb에 접근
끗ㅋ