使用引用或指针组成?

Ume*_* MS 3 c++

请告诉我哪一个好

考虑我有这样的课程

class Shape
{
public:
    virtual void Display()
    {
        cout << "Shape::Display()" << endl;
    }
};

class Line : public Shape
{
public:
    void Display()
    {
        cout << "Line::Display()" << endl;
    }
};

class Circle : public Shape
{
public:
    void Display()
    {
        cout << "Circle::Display()" << endl;
    }
};
Run Code Online (Sandbox Code Playgroud)

1)

class Container
{
public:
    Container(Shape& shape) : m_Shape(shape)
    {

    }

    void Draw()
    {
        m_Shape.Display();
    }
private:
    Shape& m_Shape;
};
Run Code Online (Sandbox Code Playgroud)

在这里,他正在参考并将其分配给基类对象.

2)

class ShapeContainer
{
public:
    ShapeContainer(Shape* pShape) : m_pShape(pShape)
    {

    }
    void Draw()
    {
        m_pShape->Display();
    }

private:
        Shape* m_pShape;
};
Run Code Online (Sandbox Code Playgroud)

他在这里获取指针并将其分配给基类对象.

请让我知道哪一个好或何时使用它们

Dav*_*eas 7

必须根据您对对象的要求做出决定.由于您不包括存储值的选项,我将假设您需要容器来引用外部对象.如果这不是必需的,请考虑使用标准容器:存储对象的副本.

通过使用引用,您可以避免在创建时检查NULL(在创建之后,两个解决方案在那里共享相同的问题:外部对象可能会被破坏,留下悬挂引用和未定义行为).引用的语义稍微强一些,读取代码的任何人都会立即理解:此容器用于在容器的整个生命周期内保存对该对象的引用,对象生存期在外部进行管理.

在它的负面,引用不可重置,一旦你设置了引用它就成为对象的别名,你不能重置它来引用另一个对象.这意味着默认情况下,保存引用的容器不可分配,因为您无法使其引用其他对象.即使您提供自定义赋值运算符,也无法更改引用,并且它将继续引用旧对象.您将无法在容器中提供成员函数来引用其他对象:一旦设置了引用,它就会永久设置.

另一方面,指针可以为NULL,因此您可能需要/需要在使用前检查指针的有效性.它们是可重置的,您可以提供操作以使容器在任何时候引用不同的对象,默认情况下容器可以分配.从消极方面来说,指针可以在不同的场景中使用,因此语义不是那么清晰.特别是,您必须在接口上仔细记录容器是否拥有指针的所有权(以及释放内存的责任).如果你要处理容器内的所有权,那么考虑使用智能指针(或者只是制作副本并忘记原始,如果可以的话,这将更不容易出错).