Работа с неполными типами - PullRequest
3 голосов
/ 02 апреля 2011

У меня есть два класса: один из них имеет неполный тип, а второй должен использовать этот неполный тип.Есть ли способ ссылки на «внешний тип», аналогично тому, как вы ссылаетесь на внешний объект?


Редактировать: Подробно о структуре моих классов.

К сожалению, я тоже не могу использовать указатели.Мой код выглядит примерно так:

class CompleteA {
  private:
    friend CompleteB;
    struct IncompleteA;
    boost::shared_ptr<IncompleteA> data_;
};

class CompleteB {
   public:
     void SomeFct(CompleteA& a) {
        // I need to access a member of the incomplete type
        a.data_->someMember;
     }
};

Я мог бы иметь отдельную пару заголовочных и исходных файлов, но это было бы немного излишним в моем случае.Неполный тип - это просто структура с одним членом;Я использую это, чтобы скрыть реализацию.(Однако, если нет другого варианта, я прибегну к отдельному заголовку ...)

О моем использовании друга, пожалуйста, проигнорируйте это и сконцентрируйтесь на том, что я прошу помочь.Я размышлял о том, должен ли я использовать здесь друга или нет, и я пришел к выводу, что использование геттеров (вместо друга) представит реализацию.

Ответы [ 3 ]

6 голосов
/ 02 апреля 2011

Используйте предварительную декларацию.

В вашем yourotherclass.h:

class IncompleteClass;

class YourOtherClass
{
    IncompleteClass* member;
};

В вашем yourotherclass.cpp вам на самом деле нужно будет включить incompleteclass.h, чтобы иметь возможность использоватьуказатель.

Редактировать: отвечая на ваши данные:

Если вы хотите скрыть реализацию, создайте для этого отдельный (друг) класс и укажите что:

class CompleteAImpl
{
    friend CompleteA;
    // data, members, etc. that you intend to hide
};

class CompleteA
{
    CompleteAImpl* priv; // or shared_ptr if you want
};

Я думаю, ты хотел сделать что-то подобное.Проблема с вашей реализацией состоит в том, что для ссылки на член struct / class компилятору необходимо знать размер этого члена и предыдущих членов.Вы можете привести свой (a.data_ + sizeof(all preceding members)) к типу someMember и разыменовать его;но это уродливое и небезопасное решение.

2 голосов
/ 02 апреля 2011

Я не мог правильно понять ваш вопрос.

Но из того, что я понимаю, я могу только сказать, что неполный тип может использоваться как pointer только в вашем коде.

struct A; //incomplete type, since it has not been defined yet!

A *pA; //okay - pointer to an incomplete type is allowed!
A  a;  //error - cannot declare an automatic variable of incomplete type!

Я надеюсь, что эта информация поможет вам найти фактическое решение вашей проблемы!

1 голос
/ 02 апреля 2011

Существует одно очень простое решение, если вам нужен только доступ к someMember: предоставить частный получатель с определением вне строки.

class A {
private:
  friend B;
  int getSomeMember() const; // defined in .cpp

  struct IncompleteA;
  boost::shared_ptr<IncompleteA> data_;
};

class B {
public:
  void SomeFct(A& a) {
    a.getSomeMember();
  }
};
...