2015-01-09 100 views
2
class bst 
{ 
private: 

typedef struct nod 
{ 
    int data; 
    nod* left; 
    nod* right; 
    nod(int key):data(key),left(NULL),right(NULL){} 
}node; 
node* root; 

public: 

void create(); 
void add(int key,node*curr=root); 
void c2ll(); 
void print(){} 

該代碼不編譯... 我得到下面的錯誤。C++默認參數類成員

ain.cpp: In function ‘int main()’: 
main.cpp:7:12: error: call to ‘void bst::add(int, bst::node*)’ uses the default argument for parameter 2, which is not yet defined 
    bt.add(50); 
      ^
In file included from bst.cpp:1:0: 
bst.h:14:8: error: invalid use of non-static data member ‘bst::root’ 
    node* root; 
     ^
bst.h:19:28: error: from this location 
void add(int key,node*curr=root); 
          ^
bst.h:14:8: error: invalid use of non-static data member ‘bst::root’ 
    node* root; 
     ^
bst.cpp:10:34: error: from this location 
void bst::add(int key,node* curr=root) 

任何建議將受到歡迎...我試圖避免編寫的包裝方法,而是使用由C++

+2

由於錯誤說你不能將默認參數設置爲非靜態成員變量。您應該重載添加以取得唯一的密鑰,並調用以root作爲第二個參數的兩個參數。 – Borgleader 2015-01-09 18:27:15

+0

@Borgleader:你應該做出答案。 – jxh 2015-01-09 18:28:55

+0

所以,這將相當於編寫一個包裝函數。無論如何,我可以逃脫,而無需編寫包裝函數? – basav 2015-01-09 18:32:29

回答

3

根據C++標準(8.3.6默認參數)

  • ...類似地,一個非靜態成員不應在默認參數使用,即使它不計算,除非它顯示爲 ID-表達一個類成員訪問表達式(5.2.5),或者除非它使用 來形成指向成員(5.3.1)的指針。 [例如:以下示例中的X :: mem1()的 聲明不合格 ,因爲未爲非靜態成員X :: a提供對象,用作初始值設定項的 。
  • int b; 
    class X { 
    int a; 
    int mem1(int i = a); // error: non-static member a 
    // used as default argument 
    int mem2(int i = b); // OK; use X::b 
    static int b; 
    }; 
    

    你可以重載函數add。例如

    void add(int key); 
    
    void add(int key, node *curr); 
    

    第一個函數將默認使用root。它可以簡單地將第二個函數作爲第二個參數傳遞給節點根。

    +0

    我遇到的問題是它是一個遞歸函數... void add( int key); ....我需要evry stack frame中的節點*,因此我將它作爲參數 – basav 2015-01-09 18:39:34

    +0

    @basav正如我在更新後的文章中寫的,第一個函數可以調用第二個遞歸函數。沒問題。 – 2015-01-09 18:40:43

    +0

    ok.got它有點類似於相互遞歸。 – basav 2015-01-09 18:44:50

    0

    使用這樣提供的默認功能: const node* root = NULL; void add(int key,node*curr=root);

    您可以檢查實際運行示例如下: http://ideone.com/tJ1r29

    +0

    hmm,如果根節點是const,最終將不可能在根節點的左側或右側添加另一個節點... – Diego 2015-01-09 19:03:09

    4

    的問題是在定義的方法:

    void add(int key,node*curr=root); 
    

    root是不是在你使用它的上下文中定義。如果您的意思是成員變量node* root,則無法在成員函數中默認成員變量,但可以將NULL(0)設置爲默認值並在定義中對其進行檢查。

    void bst::add (int key,node*curr=NULL) 
    { 
        if(curr==NULL) { 
         curr= this->root; 
        } 
    } 
    
    +1

    約定參數和成員變量的關係...很好的例子 – basav 2015-01-09 18:37:25

    2

    有兩種方法。

    要麼使用一個「神奇」默認:

    void add(int key, node* curr = NULL) 
    { 
        if (curr == NULL) 
         curr = root; 
        // ... 
    } 
    

    或完全拋棄默認和使用過載:

    void add(int key, node* curr) 
    { 
        // ... 
    } 
    
    void add(int key) 
    { 
        add(key, root); 
    } 
    

    我個人的偏好是後者,但你真的不應該暴露樹的界面中的所有節點類型,因爲這會讓樹的用戶破壞其平衡。