今天做了TomTom的第二次線上白板題測驗
雖然第一關勉強過關了,但第二關就... 果不其然被電了XDDD
目前也做了TitanSoft、趨勢跟TomTom三家外商的線上測驗了
感想就是... 真的是各種被虐啊XDDD
說到底就是不夠強嘛,再好好努力吧=ˇ=
今天來看一個我沒什麼接觸的東西,operator的overloading
除了可以overload現有的class之外,自己建立的類別也可以自己實作operator的內容
主要是參考 https://en.cppreference.com/w/cpp/language/operators
首先呢對於不同的opertor,有些只能做為member function,有些是要宣告為global function的
可以參考底下這個表格:
| Expression | As member function | As non-member function | Example |
|---|---|---|---|
| @a | (a).operator@ ( ) | operator@ (a) | !std::cin calls std::cin.operator!() |
| a@b | (a).operator@ (b) | operator@ (a, b) | std::cout << 42 calls std::cout.operator<<(42) |
| a=b | (a).operator= (b) | cannot be non-member | std::string s; s = "abc"; calls s.operator=("abc") |
| a(b...) | (a).operator()(b...) | cannot be non-member | std::random_device r; auto n = r(); calls r.operator()() |
| a[b] | (a).operator[](b) | cannot be non-member | std::map<int, int> m; m[1] = 2; calls m.operator[](1) |
| a-> | (a).operator-> ( ) | cannot be non-member | auto p = std::make_unique<S>(); p->bar() calls p.operator->() |
| a@ | (a).operator@ (0) | operator@ (a, 0) | std::vector<int>::iterator i = v.begin(); i++ calls i.operator++(0) |
|
in this table, |
...有看沒有懂嗎,大概說一下好了
反正什麼+、-、*、\這種就是第二類,可以設成global或是member都可以,只是宣告的方式不一樣
下面有幾個就不能夠設成global function,比如說=(assignment), a(b...) (copy constructor)這種
(另外關於copy constructor這種東西,C++還有一些expilict轉換的機制,下次有機會再來看看)
那麼作為member function的話要怎麼實作呢
假設有一個新的class叫做test,裡面有a, b兩個int的member
我們就先看一下=的overload怎麼做:
class test
{
int a, b;
public:
test(int a, int b) : a(a), b(b) {}
test& operator=(test other)
{
std::swap(a, other.a); // resources are exchanged between *this and other
std::swap(b, other.b);
return *this;
}
};
其實有很多種作法,可以去參考一下前面提供的連結
上面這個就是一個call by value的做法
複製一份other的值進來之後把other的member和this的member調換填完this的member,出了這個scope之後這裡的other就會直接解構了
是一個相當方便的作法
當然啦,像assignment這種operator在compiler都會預設一個給他,只是有些情況會造成memory leak... 這個之後可以再講一下XD
另外在C++11之後還有一些關鍵字,比如說在operator函式的後面加delete,表示不使用編譯器預設的operator
https://stackoverflow.com/questions/7823845/disable-compiler-generated-copy-assignment-operator
...好像扯有點遠了XD
那像+的話就有兩種做法,第一種是作為member function:
test operator+(const test& other)
{
return test(this->a + other.a, this->b + other.b);
}
這個就很簡單了,等於是建一個新的test傳回去
如果是要建成global function的話,大概是像這樣:
friend test operator+(const test& l, const test& r)
{
return test(l.a + r.a, l.b + r.b);
}
如果要寫在test這個class裡的話,前面就要加上friend,讓這個function可以去存取test裡的member
再來看一下+=這種的operator
一樣可以寫成member和global的形式:
test& operator+=(const test& rhs) // member版
{
this->a = this->a + rhs.a;
this->b = this->b + rhs.b;
return *this;
}
friend test operator+=(test& lv, const test& rv) // global版,其實這裡的lv就是*this
{
lv.a += rv.a;
lv.b += rv.b;
return lv;
}
然後像是stream(<<)這種的operator,可以寫成這樣:
friend std::ostream& operator<<(std::ostream& out, const test& t)
{
return out << t.a << ' ' << t.b;
}
其實就把out當成你要傳出去的stream就是了,然後t就是現在這個class
比較常見的就這些吧,另外像是一些==、>=這種就相對簡單了
其實我看一看也有點累了XD
如果之後真的在工作上遇到再來好好研究下吧~
這篇就這樣了~ 下篇再見~
