今天做了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, @ is a placeholder representing all matching operators: all prefix operators in @a, all postfix operators other than -> in a@, all infix operators other than = in a@b

 

...有看沒有懂嗎,大概說一下好了

反正什麼+、-、*、\這種就是第二類,可以設成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

如果之後真的在工作上遇到再來好好研究下吧~

這篇就這樣了~ 下篇再見~

文章標籤
全站熱搜
創作者介紹
創作者 頁頁頁六滴 的頭像
頁頁頁六滴

人森很精彩,所以要把所有事情都記起來=ˇ=

頁頁頁六滴 發表在 痞客邦 留言(0) 人氣(173)