Можете ли вы решить эту проблему круговой зависимости в C ++? - PullRequest
0 голосов
/ 03 июля 2011

Существует класс Object с функцией clone (), который может генерировать исключение CloneNotSupportedException * и объявляется таковым. CloneNotSupportedException происходит от Exception, которое происходит от Object.

Наследование требует полных типов, и у нас их два, поэтому очевидно, что мы не можем разорвать круговую зависимость там. Указатели-члены и параметры-указатели являются содержимым с неполными типами, но этого, по-видимому, недостаточно для объявлений броска, даже если мы бросаем указатели.

Определения классов отделены от реализаций, используются предварительные объявления, везде указатели. Этого все еще недостаточно.

Есть ли способ разорвать эту зависимость или это невозможно в C ++?

Ответы [ 3 ]

7 голосов
/ 03 июля 2011

Пропустите спецификацию исключений, это бесполезно.

class Object {
    virtual Object* clone() = 0;
    virtual ~Object() {}
};

Готово.

Кстати, ваш дизайн звучит так совершенно неправильно, я не могу заставить себя не комментировать это.

1 голос
/ 03 июля 2011
#include <memory>
#ifndef NDEBUG
  #include <typeinfo>
#endif
#include <cassert>

class Object {
public:
  typedef std::unique_ptr<Object> Ptr;  // C++0x. Use auto_ptr in 03.

  virtual ~Object() { }

  Ptr clone() const {
    Ptr obj = cloneImpl();
    assert( typeid(*obj) == typeid(*this) );
    return obj;
  }

private:
  virtual Ptr cloneImpl() const = 0;
};

Просто бросьте свое исключение по значению и поймайте его по const&. Если вы throw ваше CloneNotSupportedException исключение в cloneImpl, оно будет распространяться на вызывающего абонента, где они могут его обработать.

0 голосов
/ 03 июля 2011

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

...