01.Blogs :
kyara  
はてな始めました
Sunday, May 13, 2007 11:34 PM

最後のエントリーの日付を見たら、一年以上ほっぽいてたんですね。

なんか、こちら久しぶりって言うより使い方がもうよくわからないです。

 

で、近況ですがまあお仕事もそこそこ忙しいのでブログ自体やってなかったですけど

仕事だけに忙殺されるってのもなんか嫌なのでちょっと前からHatena::Diaryのほうで

Title::会者定離で以降

ID::murase_syuka(kyaraが既に使われていた*A*)

で、ぼちぼち書いています。

 

まあ、こちらのメンバとは、時たま会うのは2人くらいなっちゃいましたけど、

覚えていてくれる人がいれば、覗いてください^^;こちらです。

 

 

0 Comments | Post a Comment |

posted  by  kyara  with 

Unixのせかい
Tuesday, March 14, 2006 10:29 PM

ウニックス系の環境なり、言語なりをウインドウズに移植された物を使っていると

ナチュラルに、「パッチを当ててください」とか出てきます。

<メモ>

diff パッチ作成

patch パッチ適用

patch -p1 < patch_code

 

「窓にはdiffもpatchもないんです(`へ´)、MSさんおっちょこちょいだから、SFUにdiffは入れてもpatch入ってません」

えぇ、入ってません。

まあ、入れればいいんでしょうけどめんどくさいです。

他にUnix環境作るとなるとcygwin,coLinux,VMplayer,KNOPPIXなんかが、あるんでしょうけどまずcygwinは嫌です。

環境がwindowsと混ざる気がしてcygwinあんまり好きじゃないです。とか言いながら会社ではcygwinな人...orz

あと、KNOPPIXなどは簡単で便利なんでしょうけどちょっと、合わない気がします。

今回は環境が一番クリーンそうなVMplayerでも入れてみます。フリーのUnix系のイメージがいくつか一緒にあるみたいなので簡単かなって感じです。

PS、イメージのDLに結構時間懸かりそうです。

 

<追記>

ubuntu(うぶんつ?)入れてみました。最初でsound drive関連でエラー出てましたが、普通に使えそう。おいおい感想書いていきます。

しかし、これがフリーですか。いい時代ですね。

0 Comments | Post a Comment |

posted  by  kyara  with 

Webアプリのお勉強始めました
Friday, March 10, 2006 11:49 PM

一先ず、lighttpdとruby on railsの勉強中。

最近忙しいので更新もボツボツですけど、メモ代わりに書いていきます。

しかし、Linuxを走らせるセカンドマシンとして「グラタン」ほしいっす。

<3・14>

lighttpdは、apatchに比べて異様に小さいです。見たときこれだけって感じ。

現状lighttpd選んだ理由であるFastCGIの設定方法がいまいち解らないw;

0 Comments | Post a Comment |

posted  by  kyara  with 

MindMapについて
Wednesday, January 11, 2006 11:50 PM

なんか、ちょっと有名らしいMindMapを試してみようとFreeMindをインストールしてみました。

ちなみに、MindMapの詳しい説明はGoogle先生に聞いてください。結構ヒットしますし、

そもそもが、勉強においてのノートの記述の方法らしいので、紙と鉛筆があれば出来ます。

 

今年受験の人は間に合わないでしょうけど、来年以降の人は試してみればどうでしょうか。

ちょっと触ってみた感じでは良く出来てるソフトですし、暗記物(英単語、歴史等)には効果が期待できそうです。

個人的にも英語の勉強に使えるかなって、思ってます。

 

なおこれ、XPの環境では勝手に日本語になってくれるみたいですが、2000では設定自分でしなくちゃならないみたい。

<訂正>日本語化されてました。2000に入れてたのバージョン古かったです。今最新は0.8.0みたい。

0 Comments | Post a Comment |

posted  by  kyara  with 

そろそろ再開しなくては
Saturday, October 29, 2005 1:08 AM

題名のままですね。もう2ヶ月くらいなるのかな?一先ずC++のフクシュウさっさと纏めないと。それがめんどくさかったんだけどねw;

目標、週刊。こんなことばっかりいっている気が、月刊の方がいいかな。

0 Comments | Post a Comment |

posted  by  kyara  with 

<思いっきり途中です/>C++のフクシュウ<その2>
Saturday, August 20, 2005 3:12 PM

さて、次は

3、コンストラクタとデストラクタについて

コンストラクタとデストラクタについて、考えていってみまっしょい。

通常クラスの生成は、

class A
{
public:
    A(){};
    ~A(){};
};

int main()
{
    {
        A a;
        //生成されてからの寿命はスコープ間に限定
        //確保メモリはスタックに詰まれる
    }

    {
        A *pa = new A();
        delete pa;
        //寿命は開放するまで
        //動的に確保する
    }
}

下記のnew/delete表記法だと、コンストラクタとデストラクタの実行が何時起こるかは
new/deleteの実行タイミングですが、
ではでは、上記の記法だと、どうなるでしょう?

{
A a;
A::A()
}
A::~A()

って、こんな感じでした。コンパイラは、スコープを抜ける前にデストラクタ関数呼び出しを
埋め込むって感じですかね。これだとCでの実装も簡単そうですね。
CwithClassは、こんな感じでクラスを導入していったんでしょか。
ちなみに、

{
A a;
B b;
}

の場合は、

{
A::A();
B::B();
}
B::~B();
A::~A();

でした。
この辺のコンストラクタとデストラクタの順序関係は、クラスAの参照をクラスBが使っていた場合の
ためでしょうね。こんなのを見るとDXの取得した順の逆に開放を思い出しますね。
多分、似たような問題があるんでしょか?

4、仮想関数のオーバーライドについて

で、仮想関数のオーバーライドについてです。
本題ですが、引っ張っても問題なのでちゃっちゃっとやりまっしょい。

さて始めに、

class Base
{
public:
    Base(){cout<<"start Base"<<endl;};
    ~Base(){cout<<"end Base"<<endl;}
};

class Derivative : public Base
{
public:
    Derivative(){cout<<"start Deriva"<<endl;};
    ~Derivative(){cout<<"end Deriva"<<endl;};
};

int main()
{

    {
        Derivative *pd = new Derivative();
        delete pd;
    }
    cout<<endl;
    {
        Derivative *pd = new Derivative();
        Base *pb = static_cast<Base*>(pd);
        delete pb;
    }
}

//実行結果
start Base
start Deriva
end Deriva
end Base

start Base
start Deriva
end Base

上記のように派生クラスのポインタを基本クラスのポインタにキャストした後、
開放すると、派生クラスのデストラクタが呼び出されない問題があります。
結構有名な話で、これの解決策として、「デストラクタをVirtualにする」
っていうのが、常識です。

これ自体に特に問題も異論も無いのですが、私がこれを聞いた時は、なぜVirtualにすれば
問題が解決するのかずっと疑問でした。(Virtualの動作原理を良く知らなかったので)ので、調べてみたわけです。

ところで、上記の問題はdeleteに問題があり、基本クラスにキャストされて渡された元派生クラスのポインタを
基本クラスとして、deleteするので、基本クラスのデストラクタしか呼ばれません。
ですので、下記のように、キャストはしても

{
    Derivative pd;
    Base *pb = static_cast<Base*>(&pd); 
}

deleteが、なければ特に問題も無いわけです。
静的に確保したメモリ領域なので、確保した時点で開放も決まっていますが、
動的にメモリを確保し、キャストなどをした場合上記のように問題となります。

さてさて、Virtualについて考えていきます。
Virtual関数を含まない時は、

class B
{
private:
    int b1;
    int b2;
}

class D : public B
{
private:
    int d1;
    int d2;
}

int main()
{
    D* pd = new D();
    B* pb = static_cast<B>(pd);

    cout << "pd" << ' ' << (pd) << endl;
    cout << "pb" << ' ' << (pb) << endl;
    cout << "b1" << ' ' << &(pd->b1) << endl;
    cout << "b2" << ' ' << &(pd->b2) << endl;
    cout << "d1" << ' ' << &(pd->d1) << endl;
    cout << "d2" << ' ' << &(pd->d2) << endl;
}

//出力
pd 00343D98
pb 00343D98
b1 00343D98
b2 00343D9C
d1 00343DA0
d2 00343DA4

メモリ配置はこんな感じでしょう。

address        value

0x0000    *pb,*pd->B::b1
0x0004             B::b2
0x0008             D::d1
0x000C             D::d2

さて、次にVritual関数を含む時です。

class B
{
private:
    int b1;
    int b2;
    virtual void fb1();
    virtual void fb2();
}

void B::fb1()
{cout << "fb1" << endl;}
void  B::fb2()
{cout << "fb2" << endl;}

class D : public B
{
private:
    int d1;
    int d2;
}

int main()
{
    D* pd = new D();
    B* pb = static_cast<B>(pd);

    cout << "pd" << ' ' << (pd) << endl;
    cout << "pb" << ' ' << (pb) << endl;
    cout << "b1" << ' ' << &(pd->b1) << endl;
    cout << "b2" << ' ' << &(pd->b2) << endl;
    cout << "d1" << ' ' << &(pd->d1) << endl;
    cout << "d2" << ' ' << &(pd->d2) << endl;
}

address        value

0x0000    *pb,*pd->B::b1
0x0004             B::b2
0x0008             D::d1
0x000C             D::d2

| |

posted  by  kyara  (Comments Off) 

C++のフクシュウ<その1>
Saturday, July 23, 2005 5:35 PM

さてさて、新人研修も終わってある程度お仕事モードになってきました。
とは言え、新人に行き成りお仕事出すほど切羽詰った状況でもない?ようですし
私も、何でも持ってきてくださいと言えない新人エンジニアな訳でして><
で、これからプログラム漬けの毎日が始まっていきますので、
復習がてら、C++の低レベルな部分の動作を見ていこうと思います。
基礎固めということで。

注意(間違ってたらごめんなさい。ぼろくそ言って下さい。修正します)
環境として、
VS.net2003のC++コンパイラ
を、使用しています。
他の、実装では違う動作もするかもしれませんが、ここでは気にしません。
GCCの方が良いかもしれませんが、サイトがサイトなので皆さんVSが多いでしょうし^^;

最終的には、どうして継承するクラスのデストラクタをvirtualに
した方が良いのか実装の方面から、やる予定...です
一先ず、コンストラクタとデストラクタ、継承、キャスト、
仮想関数の実装方法(vptr,vtable)などを
分かりやすく纏められたらっと思ってます。




1、継承と委譲によるコンストラクタとデストラクタの動作順について

クラス継承の場合のコンストラクタとデストラクタの動作順序は
教科書にも書かれてるくらい基本的なことと思いますが、
メンバ変数としてクラスを持つ場合の順序はどうなるのでしょうか?
確認してみまっしょよい。

using namespace std;

class B1
{
public:
    B1(){cout << "B1" << endl;};
    ~B1(){cout << "~B1" << endl;};
};

class B2
{
public:
    B2(){cout << "B2" << endl;};
    ~B2(){cout << "~B2" << endl;};
};

class D:public B1, public B2
{
public:
    D(){cout << "D" << endl;};
    ~D(){cout << "~D" << endl;};
};

class I
{
public:
    I(){cout << "I" << endl;};
    ~I(){cout << "~I" << endl;};

    B1 b1;
    B2 b2;
};

int main()
{
    {
        I i;
    }
    cout << endl;
    {
        D d;
    }

    return 0;
}

//出力
B1
B2
I
~I
~B2
~B1

B1
B2
D
~D
~B2
~B1


継承の場合は、教科書どうりに

基本クラスコンストラクタ
派生クラスコンストラクタ
派生クラスデストラクタ
基本クラスデストラクタ

の、順に動作しています。

今回クラスの多重継承を用いましたが
多重継承させた基本クラスの順序は

class D:public B1, public B2

上記のコードより、先に継承させてるB1の方が優先?されてるようです。

イメージ的には、

D* pd = new D(new B2(new B1()));
delete B1( delete(B2 ( delete(D) ) ) );//修正(イメージ的にはこちらの表記ですね)

こんな感じですね。


 委譲の場合、純粋にコードの上から順番にメモリ確保されているようですが、
これは、あくまでVC++の実装ですから、他の処理系ではどうなるか分かりません。
まあ、して思いましたけど、あんまり意味ありませんね。
これよりメンバ変数のメモリ確保はコードの上部から、行なわれることが分かりますが、
それを前提にしたコードを書くべきではないでしょうね。
(どうすれば、それを前提としたコードが書けるのか分かりませんが^^;)



2、クラスが確保するメモリ領域について

次は、クラスの確保するメモリ領域について調べてみまっしょい。

int main()
{

    I *pi = new I();
    cout << pi << endl;
    cout << &(pi->b1) << endl;
    cout << &(pi->b2) << endl;
    delete pi;

    D *pd = new D();
    cout << pd << endl;
    cout << static_cast<B1*>(pd) << endl;
    cout << static_cast<B2*>(pd) << endl;
    delete pd;

    return 0;
}

//出力
00343D98
00343D98
00343D99

00343D98
00343D98
00343D99

継承の場合、B1のアドレスとDのアドレスが一致しています。
単一継承の場合、このことより派生クラスから基本クラスのアドレスへと
キャストする場合のコストがなくなります。

class B
{
private:
    int b1;
    int b2;
}

class D : public B
{
private:
    int d1;
    int d2;
}

int main()
{
    D* pd = new D();
    B* pb = static_cast<B>(pd);
}

address        value

0x0000    *pb,*pd->B::b1
0x0004                  B::b2
0x0008                  D::d1
0x000C                  D::d2

上記のような構造です。
派生クラスのメンバ変数は、基本クラスのメンバ変数の後に追加される様に、
配置されています。派生クラスは基本クラスのメンバ変数にアクセスできますから、

namespace B{
    int b1;
    int b2;
}
namespace D{

    using namespace B;

    int d1;
    int d2;
}
namespace B{
    //Bの関数
}
namespace D{    
    //Dの関数
}

こんな感じのイメージですかね。
//注意、このあたり自分の勝手な解釈です。スコープの限定?が
    どのように実装されてるかコンパイラの知識は
    乏しいもので確実なことは分かりません。

これだと、明示的なクラスDからの基底クラスBメンバ変数b1への

pd->B::b1<