使用引用或指针组成?

时间:2011-02-23 08:14:58

标签: 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;
    }
};

1)

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

    }

    void Draw()
    {
        m_Shape.Display();
    }
private:
    Shape& m_Shape;
};

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

2)

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

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

private:
        Shape* m_pShape;
};

他在这里拿指针并将其分配给基类对象。

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

4 个答案:

答案 0 :(得分:7)

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

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

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

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

答案 1 :(得分:1)

我总是喜欢尽可能使用引用而不是指针。这避免了在使用指针之前必须进行NULL检查,因为引用不能为NULL。顺便说一下,你的shape类需要一个虚拟析构函数。

答案 2 :(得分:1)

我宁愿说在这种情况下没有好坏,这只是你想要做的事情。 如果不允许用户在向量中存储NULL指针,因为这是一个要求,那么按引用使用。但是如果用户想要为10个对象保留空间但只希望初始化前3个,那么你希望能够存储NULL以便能够区分对象和空白区域。

但如上所述,这是容器的要求。

在你的情况下,我会选择参考。

答案 3 :(得分:0)

如果不需要显式控制容器类中包含的对象的生命周期,我会选择参考方法,并且可以确保传递的引用对象在容器类的生命周期内始终有效。 / p>