2

我最终写了一些代码:

Asteroid *a = new Asteroid( asteroidCollection ) ;

事实证明我不需要变量a,因为在Asteroid构造函数中,new Asteroid最终将自己添加到asteroidCollection.

所以我最终能够写:

new Asteroid( asteroidCollection ) ;

考虑到我什至不需要退货,这是不好的风格吗?我应该做到吗

asteroidCollection->createNew() ;

或者

asteroidCollection->add( new Asteroid() ) ;

?

4

4 回答 4

8

I'd say it's bad style because it's confusing when you read the code. The first thing that springs to mind is that you have a memory leak. The confusion evaporates only after looking inside of the constructor and figuring out that the object adds itself to some list to be removed later.

Also think of possible exception scenarios. It would be better to store the allocated object in a smart pointer of some sort and then add it to the collection.

于 2012-10-10T02:43:29.243 回答
5

对于你的问题,我更喜欢

asteroidCollection->add( new Asteroid() ) ;

比其他两种风格。

它比第一个好,因为new Asteroid( asteroidCollection ) ;不比类似的好

Foo( barCollection ); 

其中 Foo 是一个类,你new在它的构造函数中是一个 Bar 对象并将它添加到一个集合中,它太晦涩以至于不知道发生了什么。

它也比第二个更好,因为 IMOasteroidCollection不应该关心如何创建一个Asteroid,它是一个集合,所以做集合的工作。

于 2012-10-10T02:58:01.020 回答
1

风格问题总是有点主观。所以在某些方面我有点喜欢回答他们。这是我的2美分...

考虑一下您希望能够创建派生自的对象Asteroid并将它们添加到您的集合中。如果该add()方法碰巧调用Asteroid了可能是(或使用)虚函数的任何函数,那么您就有可能访问尚未完全构造的对象。

我认为,在构造函数中执行类似这样的操作并让用户了解正在发生的事情是令人困惑的。

我宁愿只做一个简单的功能。它甚至不必是课程的一部分......

Asteroid *CreateAsteroid( AsteroidCollection *coll )
{
    Asteroid * a = new Asteroid();
    coll->add(a);
    return a;
}

如果您确实想继续使用构造方法,您至少可以将您的原始代码行放在这个函数中,并用非常清晰的描述来注释它正在发生的事情。

基本上,尽量不要在幕后做有趣的事情。如果这是不可避免的(或在某种程度上是可取的),请尽量不要强迫编码人员理解奇怪之处,无论该编码人员是您还是其他人。

至少在这种情况下,它并不是那么奇怪。情况可能会更糟!=)

举你最后两个例子......

  1. asteroidCollection->createNew();

  2. asteroidCollection->add( new Asteroid() );

如果您知道它始终是一种Asteroid被创建的类型,并且您不希望您班级的用户担心它,我认为数字 1 很好。如果Asteroid不能跨集合共享,那么这样做是有意义的。这类似于我建议的功能,但有点使集合类提供了可能不应该的支持代码。

Asteroid如果您可以存储派生类型,或者如果您想在将小行星添加到集合之前对其进行特殊处理,则数字 2 很有用。它是所有三种方法中最灵活的。

于 2012-10-10T02:58:48.860 回答
0

这看起来真的很成问题,谁来管理小行星的寿命?

它是否真正在小行星的用户和集合之间共享,如果是这样,您可能应该对小行星有一个 shared_ptr,以便最后一个拥有它的人清理它。

如果不将小行星放入小行星集合就不可能创建小行星,则集合拥有生命周期。

如果你在堆栈上创建一个小行星会发生什么?如果我将小行星放在 unique_ptr 或 shared_ptr 中而不是直接调用 new 会发生什么,例如:

auto asteroid = std::make_shared(asteroidCollection)

它会被删除两次吗?

如果您不希望任何人对小行星做任何事情,那么小行星集合上的方法 createAsteroid 或 addAsteroid 可能更合适。简单地调用方法 createNew 听起来你正在创建一个新的 AsteroidCollection,我认为这不是你想要的。

于 2012-10-10T02:58:07.567 回答