2016-09-14 2 views
0

Предположим, что у меня есть класс, который определяется какПравило трех для внутреннего класса, внешний класс

Ах

#ifndef A_H 
#define A_H 

#include <vector> 

class A 
{ 
    int n; 
    std::vector<A::B> elements; 
    public: 
     A(); 
     A(int); 
     class B 
     { 
      int m; 
      A* a; 
      public: 
       B(); 
       B(int); 
       B(int, A*); 
     }; 

}; 

#endif 

a.cpp

#include "A.h" 

A::A() 
: n(0) 
{ 

} 

A::A(int x) 
: n(x), elements(std::vector<A::B>(n)) 
{ 
    for (int j = 0; j < this->n; j++) 
    { 
     B newElement(j, this); 
     this->elements[j] = newElement; 
    } 
} 

A::B::B() 
: m(0), a(0) 
{ 

} 

A::B::B(int j) 
: m(j), a(0) 
{ 

} 

A::B::B(int j, A* aPtr) 
: m(j), a(aPtr) 
{ 

} 

Как следует определить конструкторы копирования, перегруженные операторы присваивания и деструкторы, так что я избегаю бесконечной рекурсии при удалении и избегаю, если возможно, необходимо использовать new? A::B нуждается в указателе на A, чтобы определить операторы, которые программист может решить добавить. Кроме того, программист может принять решение написать класс C, который расширяет и C::D, расширяющий A::B

+0

Сохраните некоторые неприятности и не используйте вложенные классы. –

+0

@ThomasMatthews Я полагаю, профессор не понравится. – xinaiz

+0

В этом случае OP должен спросить профессора, а не StackOverflow. :-) –

ответ

0

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

Владение по A::elements определяется вашей декларацией. ~A собирается уничтожить любые B в элементе, принадлежащем владельцам. Это означает, что A::B::a, вероятно, должен рассматриваться как незанятый указатель и не удаляется при запуске ~B. Если при некоторых обстоятельствах A::B::a принадлежит экземпляру B, то B может потребоваться добавить участника для отслеживания этого права собственности и освободить его только при таких обстоятельствах. Альтернативно, A::B::a может быть объявлен как std::shared_ptr<A> (или аналогичный). Однако помните, что std::shared_ptr может по-прежнему протекать, если владение является круговым.

Эта двусмысленность и сложность можно было бы избежать, если бы можно было определить, «что владеет», и придумать отношения, которые менее непрозрачны, чем «все владеет всем остальным».

+0

Проблема в том, что я пытаюсь реализовать 'IntegerGroup',' IntegerRing', которые являются реализациями C++ целых групп и целых циклических структур в математике. –

+0

Кроме того, что, если был скопирован только указатель, и не было использовано 'new'? –

+0

Это предполагает неформальное слабое отношение, которое является распространенным, если небезопасным, шаблоном C++. –

Смежные вопросы