Friday, July 25, 2014

[Programming] #5 Passing by value and reference, with a pinch of const

This is going to just be a alternate perspective of the good old "pass by values vs pass by reference" programming topic.

The motivation of writing this stems from me currently in a working environment with programmers coming from so many different backgrounds and when they land into a project in C++, they tend to get lost about this only because they are not used to it (these are good programmers who actually know their shit).

The other motivation is so that when I encounter programmers who do not completely understand this, I can just copy paste this to them and hopefully they understand.

Needless to say, I would like to thank Java, javascript, PHP and all those other languages for blurring the lines between passing by reference and passing by value. THANKS =/

Anyway. This is written with cocos2d-x classes.

There are 2 ways of how you would pass an object in C++ (I will used a more extreme example like CCArray):

void foo( CCArray array ) //pass by value

and
void boo( CCArray& rArray ) // pass by reference


In the first line, the object is passed by value. This means that every time you call the function foo(), it will literally take your original CCArray, create a copy of CCArray and copy *each and every* of the original's content into the copy before the function starts. Some humans usually call this 'piracy', and while the idea of piracy is 'nice' and all, it takes up more space and it takes time to copy.

In the worse case common scenario, you might write code like this:

class SomeClass {
public:
  foo(CCArray array);
private:
  m_array;
}

void SomeClass::foo( CCArray array ) {
  m_array = array; // wut
}

// somewhere else
SomeClass myClass;
CCArray array(); // pretend that there is 1000 objects in pArray
myClass.foo(pArray);

In this case, when you call 'myClass.foo(pArray)', it will first copy pArray into a separate CCArray before the start of the function.

Within the function, thanks to the awesome assignment operator in m_array = array, it will attempt to copy the copied CCArray 'array' into a new copy 'm_array'! (Double piracy!)

This is obviously not very good. The second copying is actually fine because we want our own copy of the CCArray, but the first copying process feels redundant. Why should we copy twice for one copy?

The alternative is to pass by reference:

void SomeClass::foo( CCArray& rArray ) {
  m_array = rArray ;
}

SomeClass myClass;
CCArray pArray();
myClass.foo(pArray); // pretend that there is 1000 objects in pArray

This passes the reference; of pArray into the function, that is, the original pArray into the function. Unfortunately, because it is the original copy, it means that the function foo() can do maliciously evil despicable things like:

void SomeClass::foo( CCArray& rArray ) {
  m_array = array;

  //evil malicious things by adding 1000 more rubbish!
  for ( int i = 0 ; i < 1000; ++i ) {
    m_array->addObject(CCObject::create())
  }
}

SomeClass myClass;
CCArray array();    // pretend that there is 1000 objects in pArray

// now there are 2000 objects instead of 1000 objects in pArray and you are officially heartbroken because you might have wasted 10 hours debugging why.
myClass.foo(pArray);

This actually happens in Java often because Java people are trust each other.
However, C++ programmers do not trust each other so we have a wonderful keyword called const.

With this const keyword, we promise to the users that we will never modify their object:

void SomeClass::foo( const CCArray& array ) {
  m_array = array;

  //COMPILE ERROR!
  for ( int i = 0 ; i < 1000; ++i ) {
    m_array->addObject(CCObject::create());
  }
}

This is why you see argument declarations like "const std::string& str" being used.

But wait, what about pointers?

Pointers work exactly like a value. In other words, there is really no difference between passing by value and passing by pointer IF you treat pointers like an object on it's own (i.e, do not think about its relation to the object so much).

Pointers are simply 4 byte objects that store addresses.

Consider:
void SomeClass::foo( const CCArray *pArray ) {
  // Assume m_array is now "const CCArray * m_array"
  m_array = pArray ;
}
SomeClass myClass;
CCArray array();
myClass.foo(&array);

This simply means that the address of 'array' is copied into 'pArray' and then copied over to 'm_array'. All 3 variables are different variables (they are essentially different) but they hold the same value. Much like if you set i = j = k = 0, all i, j and k are different variables but they all hold 0. It's pretty much the same concept.

Again: Pointers store addresses.

This is not that much different:
void SomeClass::foo( const CCArray *pArray ) {
  // Assume m_array is now "const CCArray * m_array"
  m_array = pArray ;
}
SomeClass myClass;
CCArray * array = CCArray::create(); // now we try to pass by pointer
myClass.foo(array);

Okay read this slowly:

This means that the value held by 'array' is copied into 'pArray' and then copied into 'm_array'. The difference is that the former assigns the address of 'array' into 'pArray', while the latter copies the value held by 'array' into 'pArray'. Both methods have more or less the same results, although what happens is sublimely different.

While there is no deep copying involved in both cases, we must remember that this only means that 'm_array' cannot change the value of the object it is pointing to, but 'array' can. That means that if the object that 'array' is pointing to is modified, the object that 'm_array' is pointing to will be modified too.

After all, even though the pointers are different, they store the same addresses and thus they are pointing to the same object.

Thursday, July 10, 2014

軍に入る生活

はああ。。。(´・_・`)

僕は今軍に入っています。前回のポスト言う通り、ここで退屈になりました。

今まで三日もうすぎました。その間に4つことをするしかないです。この4つは寝る、ゲームを遊ぶ、食う、浴びるということです。

暇だああああ!!!

始めりの僕はたまらないほどつまんないです。幼くFacebookの友達にヤダアアと呼んじゃったw。しかし、この三日の間に、この退屈な生活になれました。。。かな。。。

暇ので、もっと打つかなw

軍のキャンプは何を呼びますか。軍営ですか。それでは軍営の環境を話しましょう。今草を切る音以外は穏やかなんです。周りは木しかない、森の中ですから。上は二つの扇風機が囁いで、ベットに休むか寝る僕とほかの四人たちに吹います。

それはなんだろ。養護ホーム??

でも皆は怪我者に過ぎない。それに僕が指定された義務所の員が多すぎるので、僕の必要はない。

確かに今度のはあまり不味くない。前回よりいいと思います。雨はよく振ったし、温度は涼しいし、湿度は低いです。退屈けど、よく休みました。

それにしても、新ロロナとラブライブを遊べます!

そう考えば、今週の生活はあまり不味くないね。

ですが、退屈は苦しいコトです。

次回の軍に入るのは二週間です(´・ω・`)

どうやって生きるかな。。。

Saturday, July 5, 2014

2014/07/05 軍に入りたくないことです

今回も日本語でしましょう!

最近仕事は忙しくなりましたね。残業するほど忙しいけど、楽しいです。一年の待つ後でやっと本当の開発仕事をいただいました!

これからもっと面白い仕事を楽しみます!

そうですね。今回の課題はやはり仕事のことですか?w

仕事のことは1つ悪い習慣がある。それは早起きられないのことです。実は、僕の3月前の出席登録を調べまして、遅刻度を引きました。一月の20営業日に平均して14日に遅刻してしまいましたね。見たとき「それはアカンや!」とおもいましたw。ですから、今月から、僕は遅刻しないようにしています!

そういえば、習慣と言えば、先週から腹が悪いので、コーヒをあまり飲まないようにしています。コーヒは好きけど、飲んだら、腹に気持ち悪い感じを与えますよ。それで、コーヒの代わりにお茶を飲みます、味が違うけど。

今まで多分一週間にコーヒを飲まなかったね。時々体は疲れて飲みたいな。。


そんなこんなで!

来週は僕が軍に入らせます! \(^O^)/

それは。。。嬉しいことではないね OTL

会社で働くのは、軍に入るより楽しいと思います。

体は怪我があるので、軍の活動できないので、ぶらぶらする以上できない。それと考えば、何もしないなら、どうして軍に入らせる必要がありますか?僕も分かりません。

それで、軍の生活はとても詰まらないです。

活動できないなら、暇になるよね。ゲームを遊べるかな?来週はラブライブが新しいイベントを広きまして参加しなきゃw


今度はのぞみですね。のぞみはあまり好きじゃないけど、カードがほしいですねw

はあ。。。。

軍に入るのは一週間だけですが、面倒くさいと感じますね。早く終わったらいいです。

休みとして過ごせるかな?そうね。そうしようか?