C++面試八股文:技術勘誤

2023-07-02 06:00:43

不知不覺,《C++面試八股文》已經更新30篇了,這是我第一次寫技術部落格,由於個人能力有限,出現了不少紕漏,在此向各位讀者小夥伴們致歉。

為了不誤導更多的小夥伴,以後會不定期的出勘誤文章,請各位小夥伴留意。

在《C++面試八股文:C++中,設計一個類要注意哪些東西?》一文中,

#include <iostream>
struct Foo{};
struct Goo
{
    void f1(Foo& f){std::cout <<"non const function" << std::endl;}	
    void f1(const Foo& f){std::cout <<"const function" << std::endl;}
};
int main(int argc, char const *argv[])
{
    Foo foo;
    Goo goo;
    goo.f1(foo);    //無法通過編譯,error: ‘void Goo::f1(Foo)’ cannot be overloaded with ‘void Goo::f1(Foo)’
    return 0;
}

這裡的例子f1f2方法的引數應該是Foo fconst Foo f,這才是頂層const。在此感謝知乎使用者 退乎 的提醒。

在《C++面試八股文:std::string是如何實現的?》一文中,

有std::string過載的相關問題,我已經在 技術勘誤:《C++面試八股文:std::string是如何實現的?》 一文中做了詳細說明,在此再次感謝知乎使用者 莊嚴 的指正。

在《C++面試八股文:override和finial關鍵字有什麼作用?》一文中,final 誤拼為 finial,感謝知乎使用者 DiaoYan 的指正。

同時,這張記憶體佈局圖也有錯誤,

應該是這樣的:

感謝知乎使用者 清越 的指正。

在《C++面試八股文:std::vector瞭解嗎?》一文中,

面試官:push_backemplace_back有什麼區別?

除了文中所說的不同點,還要一點:emplace_back可以傳入建構函式構造物件,而push_back只能拷貝或移動物件。

感謝知乎使用者 選擇公理 的指正。

在《C++面試八股文:std::vector和std::list,如何選擇?》一文中,

以下程式碼的輸出是什麼?

#include <iostream>
#include <list>
int main(int argc, char const *argv[])
{
    std::list<int> li = {1,2,3,4,5,6};
    for(auto it = li.begin(); it!= li.end(); ++it)
    {
        if(0 == *it % 2) li.erase(it);
    }
    for(auto& i : li) std::cout << i << " ";
    std::cout << std::endl;
}

這裡給出的答案是有問題的:

erase函數返回下一個有效迭代器,所以可以把if(0 == *it % 2) li.erase(it)修改為if(0 == *it % 2) it = li.erase(it)來解決這個問題。

這裡的erase返回的是下一個迭代器,然後++就是下下個迭代器,跳過了下個迭代器。但是上面程式碼中%2 == 0 也會跳過下個奇數,所以無法暴露這個問題。應該改成:

#include <iostream>
#include <list>
int main(int argc, char const *argv[])
{
    std::list<int> li = {1,2,3,4,5,6};
    auto it = li.begin();
    while(it!= li.end())
    {
        if(0 == *it % 2) 
        {
            it = li.erase(it);
        }else{
            ++it;
        }
    }
    for(auto& i : li) std::cout << i << " ";
    std::cout << std::endl;
}

感謝知乎使用者 潸然 的指正。

在《C++面試八股文:什麼是建構函式?》一文中,

面試官:可以使用virtual修飾建構函式嗎?

二師兄:不可以,因為建構函式在物件構造階段呼叫,虛表尚未建立,所以無法呼叫虛擬函式實現多型。

這裡的描述是有問題的,虛表是在編譯期生成,在建構函式執行時,可能還沒有被初始化。所以無法呼叫虛擬函式實現多型。

感謝知乎使用者 handsome乳酪 的指正。

在《C++面試八股文:什麼是空指標/野指標/懸垂指標?》一文中,

面試官:你知道0/NULL/nullptr三者之間的區別嗎?

二師兄:雖然三者都能定義空指標,但三者型別不同。

二師兄:0int型別,NULL在g++下是一個宏定義,而nullptr是有型別的;

#define NULL ((void *)0)

這裡的定義也是有問題的,完整的定義如下:

#if defined (_STDDEF_H) || defined (__need_NULL)
#undef NULL /* in case <stdio.h> has defined it. */
#ifdef __GNUG__
#define NULL __null
#else /* G++ */
#ifndef __cplusplus
#define NULL ((void *)0)
#else /* C++ */
#define NULL 0
#endif /* C++ */
#endif /* G++ */
#endif /* NULL not defined and <stddef.h> or need NULL. */
#undef __need_NULL

GCC11下,是 __null, 型別是long。所以sizeof(NULL) == 8

再再再次感謝 莊嚴 大佬的指正。

感謝小夥伴們的的反饋,這對我來說非常寶貴。不僅幫助我改正了文章中的錯誤,也讓我有機會更新和修正自己的知識儲備庫。

C++的標準繁雜,不同版本的標準可能有所出入。同時不同編譯器對標準的實現也不盡相同,這增加了C++學習者的負擔。

前路坎坷,吾輩不可因為荊棘密佈望而卻步。

關注我,帶你21天「精通」C++!(狗頭)