2016-12-25 59 views
1

我正在學習C++。 我學會了什麼時候應該在谷歌風格指南中使用「傳遞指針」或「傳遞常量引用」。 它說將指針轉換爲C++中的值會花費多少錢?

(1)如果任何成員在函數中的變化,值應該通過指針傳遞。 (2)如果任何成員在函數中沒有改變,則該值應該由const引用傳遞。

我不知道,當我有一個實例的指針,並且任何成員都不會在新函數中改變,無論我是否需要通過const引用來傳遞函數來保持谷歌風格指南。如果是這樣,我需要通過'*指針'將指針轉換爲實際值。我關心從指針轉換爲實際價值的成本,但老實說,我不知道它是否有成本。請告訴我如何在這種情況下做到這一點。

這種情況發生在我使用訪客模式時。我需要使用'this'指針,但成員不會在函數中更改。我不知道在這種情況下保留谷歌風格指南是否有任何好處或成本。

如果我複製下面的示例代碼。它是訪客模式的一部分。它有兩個使用指針傳遞和通過const引用傳遞的函數。

#include <iostream> 

class ClassA; 

class VisitorInterface { 
public: 
    virtual ~VisitorInterface() = default; 
    virtual void operator() (ClassA* obj) const = 0; 
    virtual void operator() (const ClassA& obj) const = 0; 
}; 

class VisitorsHostInterface { // = visitor's host 
public: 
    virtual ~VisitorsHostInterface() = default; 
    virtual void accept(VisitorInterface* v) = 0; 
    virtual void accept(const VisitorInterface& v) = 0; 
}; 

class VisitorsHost : public VisitorsHostInterface { 
public: 
    virtual ~VisitorsHost(); 
    void accept(VisitorInterface* v) override {}; 
    void accept(const VisitorInterface& v) override {}; 
}; 

class ClassA : public VisitorsHostInterface { 
public: 
    void print() const { std::cout << "ClassA value_ = " << value_ << std::endl; } 
    void accept(VisitorInterface* v) override { 
     (*v)(this); 
    }; 
    void accept(const VisitorInterface& v) override { 
     v(*this); 
    }; 
private: 
    int value_=11; 
}; 

class Visitor : public VisitorInterface { 
public: 
    virtual ~Visitor() = default; 
    void operator() (ClassA* obj) const override { 
     if (obj) { 
      obj->print(); 
     } 
    } 
    void operator() (const ClassA& obj) const override { 
     obj.print(); 
    } 

}; 
+4

不遵循Google風格指南。改爲遵循C++核心指南。 https://github.com/isocpp/CppCoreGuidelines – Brian

+0

@Brian:爲什麼拒絕Google風格指南?也許OP被告知要明確地遵循它。 – ShadowRanger

+0

@Brian:謝謝你告訴我另一條準則。三人投票您的評論。所以看起來你提出的建議似乎更爲標準。我會讀它。 – mora

回答

2

在你的情況下,沒有

你有兩個簽名

void accept(VisitorInterface* v) override {}; 
void accept(const VisitorInterface& v) override {}; 

他們都期待一個引用(或指針和參考,如果你想準確),所以你實際上並沒有將其轉換爲對象,在這兩種情況下,您只需將this的地址傳遞給每個接受函數

但是,如果您有

void accept(const VisitorInterface v) override {}; 

你可能調用了一個複製構造函數,這個複製構造函數可能很昂貴,這取決於它的功能。

+1

我不認爲我們可以構建一個抽象類? – Danh

+0

@Danh--不確定我是否遵循 - 你是在問一個新問題還是批評答案? – Soren

+0

批評這個問題 – Danh

1

首先,你問的問題,這些是*thisthis從性能的角度傳球之間沒有區別,當你有Thing *const Thing &作爲替代重載之間進行選擇。

但是,你的代碼有其他的困惑和問題。你在這裏有幾個不同的訪問維度,我認爲你對正交案例感到困惑。以下是我看到的情況:

  1. 您的訪問者在訪問時將保持不變,並且訪問的內容也不會更改。
  2. 你有一個訪問者在訪問時會被改變,被訪問的東西不會被改變。
  3. 您有一位訪問者在訪問時將保持不變,並且訪問的內容將被更改。
  4. 你有一個訪問者在訪問時會被改變,被訪問的東西也會被改變。

我認爲你對被訪問的事件被改變的情況以及訪問者在訪問事物時發生的變化感到困惑。如果你不是,你會有四個不同的方法,而不是兩個,或者VisitorHostInterfaceVisitorInterface中的接受方法將在不同位置有const限定符。

+0

謝謝你的明確答案。我不確定我是否完全遵循,但我使用了兩種不同的接受函數,以避免編譯錯誤;相同名稱的錯誤使用相同的參數。我應該提到它。它是一致的,但是兩個帶指針和const引用的接受函數可能和我原來的問題太相似了,它可能會引入你的警告。無論如何,再次感謝你。 – mora

+0

@mora - 如果您希望指針和常量引用版本對傳入內容的可修改性進行相同的描述,請爲指針版本「something * const」進行簽名。那麼你就是說所指的東西不能被修改。獲得你的const的權利不應該是猜測,因爲如果是這樣的話,你並不真正瞭解你在做什麼。 「const」的正確性太重要了,不能這樣做。 – Omnifarious

+0

是的,你是對的。在這種情況下,我應該使用'some_type * const'。我只專注於從指針和值轉換。再次感謝你。 – mora