开发者

C++ : Suggest names for mutating and non-mutating versions of a member function

Let's say I have an Image class and I want to provide some operations on the image, like scaling, rotating etc. I want to provide 2 types of functions for e开发者_开发百科ach operation. One that modifies the object and other that does not. In Ruby, there are functions that end in ! and indicate that this one is going to modify the argument.

Since this is not allowed in C++/Java, what would be the best naming convention. For e.g. how would you name the Mutating and non-mutating versions of img.scale()?

Thanks


One option would be to use Scale for the mutating version and ScaleCopy for the non-mutating version, since it returns a copy of the original with the operation performed on the copy.

Another option would be to make the non-mutating version a non-member function. For example,

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

I'd lean towards the non-member approach since it reduces the number of member functions in the class. To quote Herb Sutter's Monoliths Unstrung, "where possible, prefer writing functions as nonmember nonfriends."


I'd probably do

img.scale()

vs.

img.scaledCopy()


For simple verbs, I think my choice would be "Verb" for the mutator, and "asVerbed" for the non-mutator. For changed properties, I would use "setProperty" for the mutator and "withProperty" for the non-mutator.

In the case of scaling, I would use "Scale" as the mutator and "asScaled" for the non-mutator.


would you name the non-mutating versions of img.scale()?

Maybe getScaled() or createScaled().


Are you sure you need the mutating variant?

If you want to mutate the object, you can always just use the non-mutating one like this:

x = x.Scale();

And I suspect it'll even be just as efficient, due to the C++ compiler's aggressive inlining.

If you do want to implement both, you could name them Scale (nonmutating) and ScaleThis (mutating).


My advice would be to wrap Scale in its own little class, and name the "getter" operator int (or operator double, or whatever you're using for it) and the "setter" operator=.


how about python convention:

Image Image::scaled(double) const;

Or:

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


How about using a copy constructor to return an Image object based on an existing Image object but with a new scale:

Image(const Image& src, double scale);

If you want to scale and mutate the same image then you could declare a non-const method:

void setScale(double scale);

If you want to obtain the scale in a non-mutating way:

double getScale() const;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜