2012-01-13 66 views
2

我只是寫了一個inorder函數到我的二叉樹,我遇到了這個困難。爲什麼使用這個指針作爲默認參數給一個不允許的函數?

class BinaryTree 
{ 
private: 
    struct Node* o_root; 
public: 
BinaryTree() 
    { 
       o_root = new Node();  
     o_root->data = 0; 
     o_root->left = NULL; 
     o_root->right = NULL; 

    } 
    void inorder(Node*root = o_root);//Invalid 

}; 


void BinaryTree::inorder(Node* root = o_root)//Invalid 
    { 
     if(root==NULL) 
     { 
      return; 
     } 
     inorder(root->left); 

     cout<< root -> data; 

     inorder(root->right); 

    } 

我得到一個錯誤:如果我把根節點靜態這個作品的非靜態成員參考必須是相對於一個特定的對象

這是爲什麼呢?如果我有兩個二叉樹,我想要對象的特定根,而不是靜態成員。我嘗試使用這個操作符,但這給了我另一個錯誤,基本上說這個操作符在默認參數中不允許使用。

任何人都可以解釋爲什麼這不起作用,爲什麼C++拒絕使用此運算符作爲默認參數?

回答

5

這是因爲this沒有定義,也不存在,當方法被實際調用(想象結果代碼)。對於實際的成員變量也是如此(沒有指向數據的指針也無法訪問數據)。

爲了闡述這個有點多,這也將導致沒有真正定義的怪異結構,如下所示(請記住,o_root甚至私人!):

sometree->inorder(); 
// ...would essentially be the same as... 
sometree->inorder(sometree->o_root); 

如何只超載inorder() ,刪除默認參數?

基本上使用以下命令:

void BinaryTree::inorder(void) 
{ 
    inorder(o_root); 
} 

void BinaryTree::inorder(Node* root) 
{ 
    // your code as-is 
} 
+2

或者當它被寫入,你可以使'inorder'成爲Node的一個函數來完成實際的工作,然後有'void BinaryTree :: inorder(void){o_root-> inorder());'。而不是調用'mytree.inorder(some_root);',用戶可以調用'some_root-> inorder();' – 2012-01-13 13:44:29

+0

我同意你的解決方案。那可行。但我仍然不明白你的意思,爲什麼不允許。當我打電話。 mytreeobject-> inorder(),是不是這個指針指向mytreeobject?或者你是說這個指針只在函數體中有效,並且沒有在參數中定義? – 2012-01-13 13:49:02

+1

正確(指針會在紙上指向它,但不是在那個時刻「在代碼中」;在準備參數時,您仍然在呼叫者中,只能訪問公共內容,this指的是來電者 - 不是被叫者)。 'this'只在體內(和初始化列表)有效。有關標準描述的摘錄,請參閱Luchian的答案。 – Mario 2012-01-13 13:52:13

1

實際上,你可以進一步縮小問題了下來:

class A 
{ 
    int x; 
    void foo(int k = x); 
}; 

這是因爲標準是這樣說的。

您可以重載方法foo(),並呼叫foo(x)裏面。

從8.3.6/9

[...]的非靜態成員不應在默認參數 表達式中使用,即使它不計算,除非它顯示爲 ID-一個類的成員訪問表達式(5.2.5)或者除非 的表達被用來形成指針構件(5.3.1)[...]

對於洞察,可以讀取整個部分8.3 .6

+0

qoute:您必須在運行時訪問內存,獲取x的當前值並將其推入參數堆棧中,這並不真正有意義,「確切地說,爲什麼不這樣做?因爲這就是我想要的它爲什麼要做,爲什麼要阻止它做它?他們所關心的問題是什麼? – 2012-01-13 13:51:03

相關問題