20141028 (C++ new, delete, *, -> 연산자 오버로딩, ARM 소스변환)

167일차






------------

C++

------------



------- 생성자


- 다음 예제 확인


소스)

class AAA

{

private:

int num;

public:

AAA(int n=0): num(n)

{  

cout<<"AAA(int n=0) : " << num <<endl;

}

};


int main(void)

{

AAA obj1(12);

// AAA buff(); // error, 인수가 있는 생성자를 호출하는데 아무 값도 안넣어서 warning.

AAA buff; // ok, 기본 생성자를 호출하였는데, 값이 없으니 기본으로 num에 0이 들어간다.

AAA * temp = new AAA;


delete temp;


return 0;

}

결과




주석 처리된 부분을 컴파일하면 아래와 같은 warning이 뜬다.

warning C4930: 'AAA buff(void)': 프로토타입 함수가 호출되지 않았습니다. 변수 정의로 사용하려고 한 것은 아닌지 확인하십시오.






- 또 비슷한 다른 예제

소스)
class AAA
{
private:
int num;

public:
AAA(int n=0): num(n)
{  
cout << "AAA(int n=0) : " << num <<endl;
}

AAA(const AAA &ref): num(ref.num)
{  
cout << "AAA(const AAA & ref)" << endl;
}

AAA & operator=(const AAA &ref)
{
num = ref.num;
cout << "operator=(const AAA &ref) : " << num <<endl;
return *this;
}

~AAA()
{
cout << "bye~ : " << num << endl;
}

void change()
{
num = 100;
cout << "num = " << num << endl;
}
};

int main(void)
{
AAA obj1(12); // num에 12 값인 obj1 생성

obj1 = 10; // 연산자= 호출됨, num에 10 값인 임시 객체가 생성되어 obj1에 값이 복사된다.
obj1.change(); // 임시 객체와 obj1을 분간하기 위해 넣음.

return 0;
}
결과











------- 어제한 소스

- 이 경우는 new로 heap에 할당 받은 경우.
BoundCheckPointPtrArray arr(3);
arr[0] = new Point(3, 4);
arr[1] = new Point(5, 6);
arr[2] = new Point(7, 8);

- 이 경우는 stack에 할당 받은 경우.
BoundCheckPointArray arr(3);
arr[0] = Point(3, 4);
arr[1] = Point(5, 6);
arr[2] = Point(7, 8);

둘 중에 heap에 할당 받는 것이 더 빠르다.
stack에 할당 받을 경우, 임시객체가 발생해서 할당 받고, 복사해 주기 때문에 더 느려지고,
heap에 할당 받으면, 할당 받고, 주소만 받기 때문에 더 효율적이다.













------- new, delete 연산자 오버로딩


new, delete 연산자도 오버로딩이 가능하다.


우선 new 연산자가 하는 일은 다음과 같다.

1. 메모리 공간의 할당

2. 생성자의 호출

3. 할당하고자 하는 자료형에 맞게 반환된 주소 값의 형 변환


객체가 아직 만들어지지 않았는데, 이 연산자가 호출이 된다는 것은

static으로 선언됐다.


예제)

class Point

{

private:

int xpos;

int ypos;


public:

Point(int x = 0, int y = 0) : xpos(x), ypos(y)

{

cout << "Point()" << endl;

}


friend ostream& operator<<(ostream& os, const Point& pos);


void * operator new (size_t size) //new 연산자 오버로딩

{

cout << "operator new : " << size << endl;

void * adr = new char[size];

return adr;

}


void operator delete (void * adr) //delete 연산자 오버로딩

{

cout << "operator delete ()" << endl;

delete []adr;

}

};


ostream& operator<<(ostream& os, const Point& pos)

{

os << "[" << pos.xpos << ", " << pos.ypos << "]" << endl;

return os;

}


int main()

{

Point * ptr = new Point(3, 4);

cout << *ptr;

delete ptr;

return 0;

};

결과


new 연산자가 실행되는 순서와 결과에 나오는 순서가 같다.

1. 메모리 할당

2. 생성자

3. 주소값 변환


이렇게 new, delete도 연산자 오버로딩이 가능하다.

또 다음과 같이 오버로딩이 가능하다.


예제)

class Point

{

private:

int xpos;

int ypos;


public:

Point(int x = 0, int y = 0) : xpos(x), ypos(y)

{

cout << "Point()" << endl;

}


friend ostream& operator<<(ostream& os, const Point& pos);


void operator new (size_t size) //new 연산자 오버로딩

{

cout << "operator new : " << size << endl;

void * adr = new char[size];

return adr;

}


void operator new[] (size_t size) //new[] 연산자 오버로딩

{

cout << "operator new[] : " << size << endl;

void * adr = new char[size];

return adr;

}


void operator delete (void * adr) //delete 연산자 오버로딩

{

cout << "operator delete ()" << endl;

delete []adr;

}


void operator delete[] (void * adr) //delete[] 연산자 오버로딩

{

cout << "operator delete[] ()" << endl;

delete []adr;

}

};


ostream& operator<<(ostream& os, const Point& pos)

{

os << "[" << pos.xpos << ", " << pos.ypos << "]" << endl;

return os;

}


int main()

{

Point * ptr = new Point(3, 4);

cout << *ptr;

delete ptr;

return 0;

};

결과



이렇게 new, delete 연산자도 오버로딩이 가능하다.









------- *, -> 연산자 오버로딩


*, ->도 오버로딩이 가능하다.

다음 예제 확인


예제)

class Number

{

private:

int num;


public:

Number(int n) : num(n) { }

void ShowData()

{

cout << "ShowData : " << num << endl;

}


Number * operator->()

{

cout << "->" << endl;

return this;

}


Number& operator*()

{

cout << "*" << endl;

return *this;

}

};


int main()

{

Number num(20);

num.ShowData();


(*num) = 30;

num->ShowData();

(*num).ShowData();


cout << "********************" << endl;


( num.operator*() ).ShowData(); // (*num).ShowData()이 이렇게 해석된다.

num.operator->()->ShowData(); // num->ShowData()이 이렇게 해석된다.


return 0;

}

결과











--------------

ARM

--------------



------- 소스 변환


예제)

//#include "myAT91SAM7S256.h"

#include "AT91SAM7S256.h"


int main()

{

//PMC_PCER = (1<<2);


//PIO_PDR = 0xFFFFFFFF;

//PIO_PER = PA0|PA1; // Port Enable PA0~1

//PIO_OER = PA1; // PA1 is Output

//PIO_ODR = PA0; // PA0 is Input


//-> 위에 소스를 아래처럼 변환

AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA);

AT91C_BASE_PIOA->PIO_PDR = 0xFFFFFFFF;

AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA0 | AT91C_PIO_PA1;

AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA1;

AT91C_BASE_PIOA->PIO_ODR = AT91C_PIO_PA0;



while (1)

{


// if PA0 were Hi

if(AT91C_PIO_PA0 == (AT91C_BASE_PIOA->PIO_PDSR & AT91C_PIO_PA0 ))

{

// then PA1 out is Hi

AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA1;

}

// if PA0 were Lo

else 

{

// then PA1 out is Lo

AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA1;

}


}

return 0;

}








설정

트랙백

댓글