2010-09-02 14 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; 
相關問題