せっかくなので先日書いたゴミサンプルをC++で書き直してみた。
#include <iostream> #include <string> class SampleClass { public: int i; std::string s; }; class Test { public: SampleClass* methodA(SampleClass* a, SampleClass* b); }; int main(int argc, char* argv[]) { SampleClass a = SampleClass(); a.i = 1; a.s = "a"; SampleClass b = SampleClass(); b.i = 2; b.s = "b"; Test t = Test(); std::cout << "== before ==" << std::endl; std::cout << "a= " << a.i << ":" << a.s << std::endl; std::cout << "b= " << b.i << ":" << b.s << std::endl; SampleClass* c = t.methodA(&a, &b); std::cout << "== after ==" << std::endl; std::cout << "a= " << a.i << ":" << a.s << std::endl; std::cout << "b= " << b.i << ":" << b.s << std::endl; std::cout << "c= " << c->i << ":" << c->s << std::endl; delete(c); return 0; } SampleClass* Test::methodA(SampleClass *a, SampleClass *b) { a->i = 11; a->s = "A"; SampleClass b2 = SampleClass(); b2.i = 12; b2.s = "B"; b = &b2; SampleClass* c = new SampleClass(); *c = b2; return c; };
同じように作ったのだから結果は当然同じ。
ただ、戻り値cはnewしたものなので最後にdeleteしている。
この辺はJavaではそんなに意識しないことだろう。
== before == a= 1:a b= 2:b == after == a= 11:A b= 2:b c= 12:B
しかし超久しぶりにC++を書いたのでアクセス修飾子ってどうするんだっけ?と迷ってしまった。。
昔は当然と思っていたのに宣言と定義を分けるというのもかなり煩わしく感じた。
“System.out.println”と”std::cout <<" を比較すると"std::cout <<"などはプログラムを知らない人には謎の暗号にしか思えまい。。
久しぶりにC++のコードを書いて思ったのはポインタを使いたいとは思わないが、やはり概念は知っておくべきということ。
Javaで参照がどうとか勉強するよりもC++やCでポインタを学んだ方が近道な気がしている。
Javaにはガベッジコレクタがあると言ってもメモリの無駄な消費はメモリの断片化が起こってガベッジコレクタの頻発などパフォーマンスに悪影響です。インスタンスの無駄な生成自体もコストがかかりますしね。やはりJavaであってもいざというときはメモリを意識したプログラムを書くべきです。
こんなコード書いてもいいこと何もないですよ。
[java]
SomeClass a = new SomeClass();
SomeClass b = new SomeClass(); // このインスタンスが作られてすぐ捨てられる
b = a;
[/java]