[C++] operator overloading
toString 같은, 문자열 반환 오퍼레이터
1. string cast operator
캐스트 연산자를 이용한 한 방법이다.
다음과 같은 상황에서 자동으로 string으로 캐스팅해서 반환해준다.
```cpp
std::string mac_str = src_mac_addr.toString()
```
C스타일의 출력(printf)을 사용하는 경우에도 이걸 이용해서 string으로 반환 받은 다음 .c_str()을 써서 변환해서 사용하는 식으로도 쓰인다.
```cpp
class Foo {
public:
operator std::string() const { return "member to string!"; }
};
Foo foo;
std::cout << foo; // Will print "I am a foo!".
```
2. operator<<
``cpp operator<<``를 오버로딩 할 때 주의해야 할 점은, 이게 클래스의 멤버이면 안된다는 점이다. 따라서 `` friend``로 선언하거나 아예 전역 함수로 빼야 한다.
전역 함수로 빼도 파라미터 타입으로 구분할 수 있으니 둘 중 뭘 써도 상관 없고 이건 취향 차이인 듯?
`` friend``로 선언하면 클래스의 private, protected 멤버에도 접근할 수 있다는 장점은 있다.
이 오버로딩의 장점은, ``cpp cout<<``이나 ``cpp clog<<``등 어떤 스트림에든 그냥 연결해서 사용하면 된다는 점이다.
```cpp
friend std::ostream& operator<<(std::ostream& os, const MacAddr& obj) {
return os << std::hex << std::setfill('0') <<
std::setw(2) << unsigned(obj.addr[0]) << ":" <<
std::setw(2) << unsigned(obj.addr[1]) << ":" <<
std::setw(2) << +obj.addr[2] << ":" << // +나 unsigned()나 같다.
std::setw(2) << unsigned(obj.addr[3]) << ":" <<
std::setw(2) << unsigned(obj.addr[4]) << ":" <<
std::setw(2) << unsigned(obj.addr[5]) <<
std::dec << std::setfill(' '); // 시작할 때 설정했던걸 다시 풀어줘야 이후에 오는 stream에 영향이 안감.
}
```
`` const``를 붙여주기를 권장한다. ``cpp map<MacAddr, ValueCls>`` 이렇게 사용하는 경우, 맵의 키로 들어가는 요소에 다음과 같이 접근하는 경우 자동으로 const로 간주하기 때문에, const가 없다면 다음 에러가 발생한다.
```cpp
src/main.cpp:111:31: error: binding reference of type ‘MacAddr&’ to ‘const MacAddr’ discards qualifiers
std::cout << iter->first;
```
객체 생성과 동시에 대입하는건, 생성자와 operator=이 둘 다 정의되어 있어야 한다.
생성자를 정의하지 않았을 때, 다음 코드에서 이런 에러가 발생한다. (직접 MacAddr mac(_mac)을 집어넣었을 때는 이와 다른 에러가 발생하기는 한다. no matching function.)
```cpp
test.cpp:39:19: error: conversion from ‘uint8_t* {aka unsigned char*}’ to n
on-scalar type ‘MacAddr’ requested
MacAddr mac = (uint8_t*)_mac;
```
생성자가 없는 경우에는 일단 객체를 만들고 나서 대입하면 잘 된다.
```cpp
MacAddr mac;
mac = (uint8_t*)_mac;
```
생성자를 다음과 같이 정의하면 선언과 동시에 초기화 가능하다.
```cpp
MacAddr(uint8_t *target) { memcpy(this->addr, target, LENGTH); }
...
MacAddr mac = (uint8_t*)_mac;
'Languages & Frameworks > C C++' 카테고리의 다른 글
More Effective C++ (0) | 2019.01.22 |
---|---|
Effective C++ (0) | 2019.01.22 |
[C++] 구조체와 클래스의 차이 ( struct / class ) (0) | 2019.01.22 |
[C++] 다양한 mutex, lock 중 뭘 써야하나. (0) | 2018.09.13 |
[C++] 생성자에서 throw하면(exception) 객체가 없어질까? / thread는 start() 함수로? (0) | 2018.09.12 |