'this'에 해당되는 글 1건

4장정리

C++프로그래밍/C++ 2007. 7. 16. 10:59

1. 정보은닉
객체의 외부에서 객체내에 존재하는 멤버변수에 직접 접근하는것을 허용하지 않는것.

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

class Point
{
public:
 int x;
 int y;
};

int main()
{
 int x,y;
 cout<<"좌표입력 : ";
 cin>>x>>y;

 Point p;
 p.x=x;
 p.y=y;

 cout<<"입력된 데이터를 이용해서 그림을 그림"<<endl;
 return 0;
}

 설명: 클래스 외부에서 내부의 변수에 직접 접근을 하였다.
         클래스 객체의 정보가 노출이 된 상태.

#include <iostream>

using std::cout;
using std::endl;
using std::cin;

class Point
{
 int x;
 int y;

public:
 int GetX()
 {
  return x;
 }
 int GetY()
 {
  return y;
 }
 void SetX(int _x);
 void SetY(int _y);
};
void Point::SetX(int _x)
{
 if(_x<0 || _x>100)
 {
  cout<<"x좌표 입력오류 ,확인요망"<<endl;
  return ;
 }
 x=_x;
}
void Point::SetY(int _y)
{
 if(_y<0 || _y>100)
 {
  cout<<"y좌료 입력오류 ,확인요망"<<endl;
  return ;
 }
 y=_y;
}

int main()
{
 int x,y;

 cout<<"좌표입력 : ";
 cin>>x>>y;

 Point p;
 p.SetX(x);
 p.SetY(y);

 cout<<"입력된 데이터를 이용해서 그림을 그림"<<endl;
 return 0;

}

설명 : 클래스 객체 외부에서 클래스 객체 내부로 직접 접근이 불가능한 상태.
         GetX,GetY라는 함수로 변수에 접근을 한다음 반환되는 값으로
         SetX,SetY라는 함수에서 연산을 하고 있다. 직접접근이 아니므로
         정보가 은닉이 된 상태. 또한 SetX,Y함수에서 클래스 객체내의 변수에 대한
         경계검사가 이루어졌다..

클래스에서 아무런 선언이 없으면 접근 제어의 default값으로 private가 적용이된다.
그러나 C의 구조체에서는 default값은 public 이다


2. 캡슐화 (Encapsulation)
캡슐화란 관련있는 데이터와 함수를 하나의 단위로 묶는것이다.

#include <iostream>

using std::cout;
using std::endl;
using std::cin;

class Point
{
 int x;
 int y;
public:
 int GetX(){return x;}
 int GetY(){return y;}
 void SetX(int _x);
 void SetY(int _y);
}

class PointShow
{
public:
 void ShowData(Point p)
 {
  cout<<"x좌표 : "<<p.GetX()<<endl;
  cout<<"y좌표 : "<<p.GetY()<<endl;
 }
};
int main()
{
 int x,y;
 cout<<"좌표입력 :";
 cin>>x>>y;
 Point p;
 p.SetX(x);
 p.SetY(y);
 PointShow show;
 show.ShowData(p);
 return 0;
}

설명: 현재 x,y와 관련된 데이터와 함수가 두개의 클래스로 나뉘어져있다..
        적절한 캡슐화가 필요하다.
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
class Point
{
 int x;
 int y;
public:
 int GetX(){return x;}
 int GetY(){return y;}
 void SetX(int _x);
 void SetY(int _y);
 void ShowData();
};
int main()
{
 int x,y;
 cout<<"좌표입력 :";
 cin>>x>>y;
 Point p;
 p.SetX(x);
 p.SetY(y);
 p.ShowData();
 return 0;
}
설명: 위의 예제에서 두개의 클래스로 나뉘어졌던 것을 하나로 캡슐화 시켰다.
        캡슐화의 개념에 대해서 확실히 알아두자.

캡슐화와 정보은닉 두가지 특성을 가진 클래스는 좋은 클래스라고 할수있다



3. 생성자와 소멸자

생성자
객체 생성시 반드시 호출된다.
객체를 생성과 동시에 초기화 할수있는 메커니즘.
함수이며 클래스의 이름과 같은 이름을 지니고 리턴타입이 없으며 리턴하지도 않는다.

모든 객체는 1)메모리할당 , 2)생성자 호출 의 과정을 반드시 거치게 되어있다
.

#include <iostream>

using std::cout;
using std::endl;
const int SIZE=20;

class AAA
{
 int i,j;
public:
 AAA(int _i,int _j)      //생성자
 {
  i=_i,j=_j;
 }
 void ShowData()
 {
  cout<<i<<' '<<j<<endl;
 }
};
int main()
{
 AAA aaa(111,222);  // (설명)
 aaa.ShowData();
 return 0;
}

 설명: AAA클래스의 객체를 생성하되 이름은 aaa이고 생성자호출시 111,222를
         인자로 전달받을수 있는 생성자를 호출하라.

Default생성자
생성자를 하나도 정의하지 않으면 Default 생성자가 자동삽입된다.
생성자도 함수이다 .그러므로 오버로딩도 가능하고 디폴트 매개변수의 설정도 가능하다.
class Point
{
   int x,y;
public:
   Point(){}
}
디폴트 생성자의 예
하는일은 아무것도 없다. 생성자를 정의하지 않으면 컴파일러에 의해 화면에는 보이지 않지
만 자동적으로 삽입이 된다.

#include <iostream>

using std::cout;
using std::endl;

class Point
{
 int x,y;
public:
 Point()  
 {
  x=y=0;
 }
 Point(int _x,int _y)
 {
  x=_x,y=_y;
 }
 void ShowData()
 {
  cout<<x<<' '<<y<<endl;
 }
};
int main()
{
 Point p1(10,20);
 p1.ShowData();
 Point p2; // void생성자 호출 하는것
 Point p2(); // 이건 생성자에게 void로 매개변수를 전달하는것이 아니라 p라는 함수를
                //  호출 하는것이다.
                //  class의 객체생성시 void매개변수를 전달할때는 Point p2; 이렇게
               //   해야한다는 일종의 약속.
 p2.ShowData();
 return 0;
}

소멸자
소멸자도 생성자와 같이 객체를 생성하게 될때 반드시 호출된다.
모든 객체는 반드지 1)소멸자 호출 , 2)메모리반환 의 과정을 거쳐서 소멸된다.
소멸자도 함수이며 클래스의 이름앞에 ~가 붙은 형태의 이름을 지닌다.
리턴하지도 않고 리턴타입도 선언되지 않으며 매개변수를 받을수가 없다
따라서 오버로딩도 할수가 없고 디폴트 매개변수의 선언이 불가능하다

#include <iostream>

using std::cout;
using std::endl;

class AAA
{
public:
 AAA()
 {
  cout<<"생성자호출"<<endl;
 }
 ~AAA()  // 소멸자의 형태
 {
  cout<<"소멸자호출"<<endl;
 }
};
int main()
{
 AAA aaa1;
 AAA aaa2;
 return 0;
}

소멸자도 정의를 해주지 않으면 Default 소멸자가 호출이 된다.
즉. 클래스 객체 내에서 생성자와 소멸자를 정의해주지 않으면
Default 생성자와 소멸자가 자동으로 호출이 된다.하지만 하는일은 없다.
class Point
{
   int x,y;

public:
   Point(){}
   ~Point(){}

   void Print(){...}
}

4. 클래스와 배열


두가지 코드를 보고이해해라. 이건 어떻게 설명을..음.

#include <iostream>

using std::cout;
using std::endl;

class Point
{
 int x;
 int y;
public:
 Point(){
  cout<<"Point() call"<<endl;
  x=y=0;
 }

 Point(int _x, int _y)
 {
  x=_x;
  y=_y;
 }

 int GetX(){return x;}
 int GetY(){return y;}
 void SetX(int _x){x=_x;}
 void SetY(int _y){y=_y;}
};

int main()
{
 Point arr[5]; //객체배열

 for(int i=0; i<5; i++)
 {
  arr[i].SetX(i*2);
  arr[i].SetY(i*3);
 }
 for(int j=0; j<5; j++)
 {
  cout<<"x: "<<arr[j].GetX()<<' ';
  cout<<"y: "<<arr[j].GetY()<<endl;
 }
 return 0;
}


Point arr[5];
객체배열, 즉, Point객체 5개의 배열이 생성된것.배열안에 객체가 존재.

int main()
{
 Point* arr[5]; //객체포인터배열

 for(int i=0; i<5; i++)
 {
  arr[i]=new Point(i*2,i*3);
 }
 for(int j=0; j<5; j++)
 {
  cout<<"x: "<<arr[j]->GetX()<<' ';
  cout<<"y: "<<arr[j]->GetY()<<endl;
 }
 for(int k=0; k<5; k++)
 {
  delete arr[k];
 }
 return 0;
}


Point* arr[5];
Point객체 5개를 가리킬수 있는 포인터배열.


5. this 포인터(자기 참조 포인터)

#include <iostream>

using std::cout;
using std::endl;

class Person
{
public:
 Person(){}

 Person* GetThis()
 {
  return this;
 }
};

int main()
{
 cout<<"*****p1의정보*****"<<endl;
 Person* p1 = new Person();
 cout<<"포인터p1:"<<p1<<endl;
 cout<<"p1의 this:"<<p1->GetThis()<<endl;

 return 0;

}



사용자 삽입 이미지

this포인터의 용도

#include <iostream>

using std::cout;
using std::endl;

class Data
{
 int aaa;
 int bbb;
public:
 Data(int aaa, int bbb)
 {
  //aaa=aaa;
  this->aaa=aaa;
  //bbb=bbb;
  this->bbb=bbb;
 }
 void printAll()
 {
  cout<<aaa<<" "<<bbb<<endl;
 }
};

int main()
{
 Data d(100,200);
 d.printAll();
 return 0;
}


생성자 Data를 보면 매개변수로 aaa,bbb로 받고 있다.
매개변수도 지역변수이므로 주석 처리되있는 부분은 전부다 생성자의 매개변수에 해당한다.
그러나 this포인터를 사용하면 private로설정되어있는 변수에 접근이 가능하다.

6. friend선언
friend선언을 통해 private로 선언된 멤버변수에 접근이 가능하다.

클래스에 대한 friend선언과 전역함수에 대한 friend선언이 가능한데..
사용하지 말래..ㅋㅋ
일단 소스코드만 첨부


friend선언은 정보은닉에 위배된다.

블로그 이미지

百見 이 不如一打 요 , 百打 가 不如一作 이다.

,