三法则适用于内类和外类

Rule of three for inner class, outer class

本文关键字:适用于      更新时间:2023-10-16

假设我有一个定义为

的类

A.h

#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的指针来定义程序员可以决定添加的操作符。同样,程序员可以决定编写扩展A的类C和扩展A::B

的类C::D

如何定义复制构造函数、重载赋值操作符和析构函数,以避免删除时的无限递归,并尽可能避免使用new

A::elements的所有权由您的声明决定。~A将销毁owned elements成员中的所有B。这意味着A::B::a可能必须被视为一个无主指针,并且在运行~B时不会被删除。如果在某些情况下,A::B::aB的一个实例拥有,那么B可能需要添加一个成员来跟踪这个所有权,并仅在这些情况下释放a。或者,可以将A::B::a声明为std::shared_ptr<A>(或类似的)。但是,请记住,如果所有权是循环的,std::shared_ptr仍然可能泄漏。

如果有可能确定"什么拥有什么",并提出一种比"一切拥有其他一切"更不透明的关系,则可以避免这种模糊性和复杂性。