Почему использование этого указателя в качестве параметра по умолчанию для функции запрещено? - PullRequest
2 голосов
/ 13 января 2012

Я только что написал функцию 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 ++ отказал в использовании этого оператора в качестве аргументов по умолчанию?

Ответы [ 2 ]

5 голосов
/ 13 января 2012

Это потому, что 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
}
1 голос
/ 13 января 2012

На самом деле вы можете еще больше сузить проблему:

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

Это потому, что так сказано в стандарте.

Вы можете перегрузить метод, foo() и вызвать foo(x) inside.

Начиная с 8.3.6 / 9

[...] Нестатический член не должен использоваться в выражении аргумента по умолчанию, даже если он не оценивается, если толькоон появляется как id-выражение выражения доступа к члену класса (5.2.5) или если он не используется для формирования указателя на член (5.3.1) [...]

Для пониманияВы можете прочитать весь раздел 8.3.6

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...