Подружиться с классом - PullRequest
       6

Подружиться с классом

1 голос
/ 25 августа 2010

Я пытаюсь подружиться с классом, чтобы он мог связаться с его частным конструктором.

В some_file.h

class B;    

namespace some_name {
class A {
  public:
    A() {}
  private:
    A (int x) {}
    friend class ::B;
};
}

В other_file.h

#include "some_file"

namespace {
class B {
  protected:
    A* get_a(int x) { return new A(x); }
};   
}

При компиляции этого кода я получаю сообщение об ошибке: 'some_name :: A :: A (int)' является приватным.

Теперь я приватный, поэтому я подружилсяB. Что я здесь не так делаю?Разве ты не можешь подружиться со своим конструктором?Есть ли проблема с пространством имен?

Спасибо

Ответы [ 4 ]

9 голосов
/ 25 августа 2010

Делая это:

namespace {
class B {
  protected:
    A* get_a(int x) { return new A(x) };
}   
}

Вы не помещаете B в корневое (глобальное) пространство имен, а в анонимное.

Так что B не может бытьдостигнут ::B.

Если вы хотите, чтобы B находился в корневом (глобальном) пространстве имен, просто не заключайте его в namespace.Это должно сработать.

1 голос
/ 25 августа 2010

Вы только вперед объявили и подружились с классом B в глобальном пространстве имен. Не класс B в пространстве имен. Вам необходимо полностью указать имя Б.

Редактировать: Спасибо, ereOn.
Я сделал небольшую ошибку. Это правда, что причина того, что у вас есть проблема, в том, что вы неправильно заявили и неправильно сослались на B, но мое первоначальное утверждение было не совсем верным. Вам нужно вывести B из анонимного пространства имен - в любом случае бессмысленно находиться в заголовке.

0 голосов
/ 25 августа 2010

Разве вы не можете подружиться со своим конструктором?

Вы можете, как показано ниже

struct B{
    B();
    void f();
};

struct A{
    friend B::B();
private:
    A(){}
};

B::B(){A a;}       // fine

void B::f(){A a;}  // error

int main(){
}
0 голосов
/ 25 августа 2010

Проблема в том, что вы ссылаетесь на B как ::B вместо B.То есть вы говорите компилятору, что B - это глобальное имя, но на самом деле это не так: оно находится внутри анонимного пространства имен.Вам не нужно удалять анонимное пространство имен, просто оно может не выполнять то, что вы ожидаете.Поскольку анонимное пространство имен находится в заголовке, это означает, что то, что находится внутри этого пространства имен, статически связано с любым файлом реализации, который содержит заголовок.Это не очень полезно, потому что вы ничего не скрываете.Вы также можете удалить это анонимное пространство имен.

...