2010-09-02 37 views
1

假设我有一个Image类,并且想对图像提供一些操作,如缩放,旋转等。 我想提供2种类型的每个操作的功能。一个修改对象,另一个不修改。 在Ruby中,有一些函数以!并表明这一个将要修改论点。C++:为成员函数的变异和非变异版本建议名称

由于C++/Java不允许这样做,所以最好的命名约定是什么。 例如你会如何命名img.scale()的突变和非突变版本?

感谢

+0

类似的问题:http://stackoverflow.com/questions/521893/whats-the-best-name- for-a-non-mutating-add-method-on-an-immutable-collection – 2010-09-02 23:05:01

+0

你为什么要问C++/Java,但只是把它标记为C++? – fredoverflow 2010-09-03 00:04:23

+1

Nit,!在红宝石并不意味着修改,但它是一个危险的非版本!一。比较退出和退出!例如。 – 2010-09-03 01:16:28

回答

10

一种选择是使用Scale的变异版本和ScaleCopy对于非变异版本,因为它返回原来的副本与副本执行的操作。

另一种选择是使非变异版本成为非成员函数。例如,

Image Scale(Image im, double scale_factor) { 
    im.Scale(scale_factor); 
    return im; 
} 

我倾向于非成员方法,因为它减少了类中成员函数的数量。引用Herb Sutter的Monoliths Unstrung,“在可能的情况下,更喜欢将函数作为非成员非友人。”

+0

所以这里的交易是先im复制,然后缩放,然后按照RVO返回。 因此,总体上你只有1个副本发生。对? – user855 2010-09-02 23:17:11

+0

@ajay,没错。 – 2010-09-02 23:29:09

+0

@ajay或'Image&Scale(Image&im,double scale_factor){' – Anycorn 2010-09-02 23:55:14

3

我可能会做

img.scale() 

img.scaledCopy() 
2

将你的名字img.scale的非突变版本()?

也许getScaled()createScaled()

+0

我不希望看起来很迂腐,但有一些可能的含糊不清:是否'返回给我一个新的缩放或/这个/,缩放? ..并做'createScaled'覆盖/这一个/缩放图像? – JBRWilkinson 2010-09-03 08:24:13

+0

@JBRWilkinson如果你对这些方法做什么有疑问,难道你不看签名:我认为不可变的方法需要通过值返回新的对象。 – ChrisW 2010-09-03 08:27:43

3

对于简单的动词,我认为我的选择将是“动词”的增变,“asVerbed”的非增变。对于更改的属性,我会使用“setProperty”作为增变器,“withProperty”使用不增变器。

在缩放的情况下,我会使用“Scale”作为增变器,“asScaled”使用非增变器。

0

我的建议是包装Scale在自己的小类,并将其命名为“吸气” operator int(或operator double,或者你使用它的任何)和“二传手” operator=

1

你确定你需要突变变异?

如果你想发生变异的对象,你总是可以只使用非突变一个这样的:

x = x.Scale(); 

而且我怀疑它甚至会在同样的高效性能,由于C++编译器的攻击性内联。

如果你确实想要实现这两个,你可以将它们命名为Scale(nonmutating)和ScaleThis(mutating)。

+0

同时具有变异和非变异版本的原因之一是对象可以定义两个线程试图同时执行突变的效果(例如,线程安全队列可以指定如果两个线程同时写入,结果将是就好像是一个人写的,然后是另一个)。有两个线程说myQueue = MyQueue.withAddedObject(objectToAdd)可能会导致一个对象被添加和另一个迷路。 – supercat 2010-09-03 00:56:00

+0

突变在两种情况下是不好的:(1)在强烈不鼓励对象变异的语言中,例如Java; (2)需要多线程支持时。如果一个对象可以被两个线程访问,那么从一个线程中改变对象(例如,可能会改变图像的尺寸)会导致第二个线程发生意外错误,因为第二个线程可能不会期望图像改变。 – rwong 2010-09-03 01:35:48

0

怎么样蟒蛇约定:

Image Image::scaled(double) const; 

或者:

Image im(other, scale); 
Image im = Image(other).scale(1); // should be okay I think 
0

如何使用拷贝构造函数返回基于现有图像对象,但一个新的大规模的Image对象:

Image(const Image& src, double scale); 

如果你想缩放和变异相同的图像,那么你可以声明一个非const方法:

void setScale(double scale); 

如果你想获得一个非不同诱变方式规模:

double getScale() const; 
相关问题