1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | ///////////// //대입 연산자// //////////// class CCopyStudy { public: CCopyStudy(int nParam) { m_pnData = new int; *m_pnData = nParam; } //얕은 복사의 오류를 범하지 않기 위해 값을 복사한 깊은 복사 형태// CCopyStudy(const CCopyStudy &rhs) { m_pnData = new int; *m_pnData = *rhs.m_pnData; } //단순대입 연산자를 사용했을시 얕은 복사 방지를 위한 코드 추가// CCopyStudy& operator=(const CCopyStudy &rhs) { *m_pnData = *rhs.m_pnData; return *this; } ~CCopyStudy() { delete m_pnData; } int GetData() { if(m_pnData != NULL) { return *m_pnData; } return 0; } private: int *m_pnData = nullptr; } int main(void) { CCopyStudy a(10); //매개변수를 통한 복사// //얕은 복사를 방지 하기 위한 깊은 복사 형태를 주의 해야 됨// CCopyStudy b(a); //단순 대입 연산자를 사용 하게 될 경우 오류가 발생// //단순 대입 연산자는 얕은 복사를 사용하게 되어서 메모리 해제시 오류가 발생// //operator 단순 대입 연산자를 사용 해야 됨// CCopyStudy c(20); a = c; //a.operator(c); //사용 방법이 2가지가 있음// return 0; } | cs |
c++
- 단순 대입 연산자 2018.03.26
- C++ 캡슐화 2015.04.03
- C++ 정보은닉 2015.04.03
- C++ delegate 쉽게 구현 한 예제 2014.06.19
단순 대입 연산자
C++ 캡슐화
캡슐화와 정보은닉의 개념이 헷갈릴수가 있다. 아래의 예를 통해서 캡슐화를 알아 보자
class Key
{
public:
void Key()
{
cout<<"키를 꼽습니다."<<endl;;
}
};
class StartButton
{
public:
void Button()
{
cout<<"시동 버튼을 누릅니다."<<endl;
}
};
class Car
{
public:
void TakeKey(Key &key);
void TakeStartButton(StartButton &button);
};
int main(void)
{
Key key;
StartButton button;
Car car;
car.TakeKey(key);
car.TakeStartButton(button);
return 0;
}
위 코드는 간략하게 자동차 시동을 켜는 방법을 클래스다. 그러나 위 예제가 캡슐화가 무너진 대표적인 예다. 왜냐 하면 자동차는 항상 키,시동버튼 행동을 포함 하게 된다. 또한 눈으로 확인 가능 하기가 어렵다.
따라서 아래 코드 처럼 변경 하면 좋다.
class Key
{
public:
void Take()
{
cout<<"키를 꼽습니다."<<endl;;
}
};
class StartButton
{
public:
void Take()
{
cout<<"시동 버튼을 누릅니다."<<endl;
}
};
class CarStart
{
private:
Key key;
StartButton btn;
public:
void Take()
{
key.Take();
btn.Take();
}
};
class Car
{
public:
void TakeCarStart(CarStart &start)
{
start. Take();
}
};
int main(void)
{
CarStart carStart;
Car car;
car. TakeCarStart(carStart);
return 0;
}
여기서 가장 중요한 것은 캡슐화의 범위를 결정 하는 일이 쉽지 않다는 것이다.
C++ 정보은닉
먼저 어떠한 좌표를 저장 하는 클래스를 기본적으로 만들어 보자
class Point
{
public:
int x; //x 좌표는 0보다 커야 한다.
int y; //y 좌표는 0보다 커야 한다.
}
int main(void)
{
Point p1 = {-2,4};
Point p2 = {3,5};
return 0;
}
위 코드를 보듯이 Point 멤버 변수 x,y를 public로 선언을 하는 바람에 어디서든 접근이 가능 하게 되어 버렸다. 따라서 0보다 작은 수를 실수로 저장이 되어 버리는 현상이 발견 되었다. 이 부분을 방지 하기 위해서 임의로 막아 주는 부분이 필요 하다.
Point.h 파일
class Point
{
private:
int x;
int y;
public:
void InitMembers(int xpos,int ypos);
int GetX();
int GetY();
bool SetX(int xpos);
bool SetY(int ypos);
}
Point.cpp 파일
bool Point::InitMembers(int xpos,int ypos)
{
if(xpos < 0 || ypos < 0)
{
return false;
}
x = xpos;
y = ypos;
return true;
}
int Point::GetX()
{
return x;
}
int Point::GetY()
{
return y;
}
bool Point::SetX(int xpos)
{
if(xpos < 0)
{
return false;
}
x = xpos;
return true;
}
bool Point::SetY(int ypos)
{
if(ypos < 0)
{
return false;
}
y = ypos;
return true;
}
위 코드 처럼 Point 멤버 변수 x,y를 숨겨서 개발자가 실수를 최대한 줄여 줄수 있게 하는 방법 입니다.
또한 GetY(),GetX() 를 GetY() const ,GetX() const를 함으로써 더욱 안정성을 높여 주는 것도 하나의 방법이다.
C++ delegate 쉽게 구현 한 예제
참고 : http://plming.tistory.com/52
include <iostream>
using namespace std;
class Animal;
class AnimalDelegate{
public:
virtual void onSound(Animal* pSender)=0;
virtual void onWalk(Animal* pSender)=0;
};
class Animal{
private:
AnimalDelegate* delegate;
public:
Animal(){
this->delegate = NULL;
}
void setDelegate(AnimalDelegate* delegate){
this->delegate = delegate;
}
void sound(){
if(this->delegate){
this->delegate->onSound(this);
}
}
void walk(){
if(this->delegate){
this->delegate->onWalk(this);
}
}
};
//개 : Delegate를 내부에 직접 구현
class Dog:public Animal, public AnimalDelegate{
public:
Dog(){
this->setDelegate(this);
}
void onSound(Animal* pSender){
cout << "Dog: 멍멍!" << endl;
}
void onWalk(Animal* pSender){
cout << "Dog: 개가 걷는다" << endl;
}
};
//고양이 Delegate
class CatDelegate:public AnimalDelegate{
public:
void onSound(Animal* pSender){
cout << "Cat: 야옹~" << endl;
}
void onWalk(Animal* pSender){
cout << "Cat: 고양이가 걷는다" << endl;
}
};
//고양이
class Cat:public Animal{};
void main(){
Dog dog;
Cat cat;
dog.sound();
dog.walk();
CatDelegate cdel;
cat.setDelegate(&cdel);
cat.sound();
cat.walk();
getchar();
}