皆さんこんばんわ
SAIです。

 

今では一般的になった段ボールPCですが、

2000年くらいの話です。

 

当時、SAIは貧乏学生でした。

 

貧乏学生なので、完成品PCなんて買えず、自作をするわけですが、

ケースって意外と高くって、当時安いケースでも1万円以上していました。

 

そんなわけで、ケチケチPCを自作したわけです。

 

今ではよく聞く段ボールPCですが、2000年前半からやっていた私。

時代の最先端!(笑)

 

 

マザーボードにスペーサーを9本付けて、段ボールに入れて使っていました。

 

CPUはPentium3ですよ。 CupperMine 650MHzだったと思います。

メモリは256MB×2枚

グラフィックボードは、当初はオンボードでしたが、

後にPCIのGeForce4200だったか、5600だったかを追加したのですよね。

(ちなみに、見ての通りPCIエクスプレスではない)

 

PICでLANカードを付けていたので、こんなでもインターネットを使えるPCでした。

 

ちなみに、当時は高価だった10GBのHDDと21GBのHDDを接続していました。

 

 

段ボール箱ってことは、起動スイッチやリセットスイッチがないですよね。

 

心配ありませんよ。

黄色い配線の下あたりに、ジャンパーピンが沢山出ています。

 

起動方法は、なんと!

ボールペンでショートをさせて起動させていました(笑)

 

Pentium3って意外と省電力だったのですよね。

 

 

 

このPC。

普通の人が見たらゴミですよね。。。

 

結婚したときに、嫁にごみ扱いされて捨てられたのでした。

 

テユアラティン時代のCeleronや、Pentium2のでっかいやつ、PC98のPentiumたちとともに。。

 

 

 

ま、今となっては結局のところ、今のスマホの能力に負けるゴミであるとは思います。

 

懐かしい写真でした。

 

みなさんこんにちわ、こんばんわ

SAIです。

 

さて、前回はC言語で関数ポインター呼び出しを勉強しました。

 

 


これを使いこなせたら便利ですよね?

 

じゃ、これをC++言語でもやってみましょうか!

 

改造のもとにするコードは、↓この日記のソースにしましょう。

 

 

 

A-4は7セグを1秒ごとに数字をカウントするプログラムですね。

 

1秒ごとの呼び出しを改造したいので、改造すべき処理を抜粋すると、

以下のコードが1秒ごとに呼び出していましたね。

--------------------------------------------------------

  CSegControlClass  lSegCtrlClass(C_7SegSetter);
 
  /* 3つを同時に点灯 */
  for(int i=0 ; i < 100;i++)
  {
    lSegCtrlClass.SetOutput(i);      //  1秒ごとにカウントアップ //
    delay(1000);
  }

-------------------------------------------------------

 

これを関数ポインタに変更すればいいわけです。(あっさり)

 

C言語の方法を流用して記載するとこんな感じになりますね。

 

-------------------------------------------------------

/* 定数定義 */

// 関数配列 //
typedef void (*pFunc)(int aNum);

pFunc FunctionList[] =
{
  &CSegControlClass::SetOutput   /* 機能1 7Seg表示関数 */
};

-------------------------------------------------------

~中略~

  /* 3つを同時に点灯 */

  for(int i=0 ; i < 100;i++)
  {

    (void)(FunctionList[0])(i);      //  1秒ごとにカウントアップ //
    delay(1000);
  }

-------------------------------------------------------

 

 

・・・なのですが、

 

じつはこれ、ビルドエラーになります。

  cannot convert 'void (CSegControlClass::*)(int)' to 'pFunc {aka void (*)(int)}' in initialization  

 

言っている意味が分かりにくいですよね。

 

パッと見は”型があっていません”といっているように見えますが、

実際のところは、全然違うところにあるんです。

 

関数ポインタ呼び出しですが、

文字通り、関数のポインタから呼び出すというものです。

 

 

今回C言語で呼び出ししようとしている関数ですが、

クラスのメンバー関数です。

 

以前少し触れましたが、

クラスってC言語でいうと、構造体のようなもので、型を定義している状態であり、

関数のポインタが存在していない状態なのです。

(厳密には、関数はROM領域に配置されるんですが、直接実行できるものではないんです。とある情報が足りない。

 

思い出してください。

構造体のポインタを示すためには、該当の構造体の実体が存在する必要がありますよね?

ROMに配置されて、どこのデータがその変数なのかわからないと、

アドレスにしたくても無理です。

 

また、実体にするにしても、構造体は定義を変えれば沢山作成できますよね。

同様に、クラスもたくさん作れるのです。

 

CSegControlClassの実体を複数個作成した場合、

どのクラスのどの変数や関数が、呼び出したいデータ(アドレス)になるのかわかりませんよね?

 

というわけで、エラーになるわけです。

 


なんとなく理解できたでしょうか?

 

 

実は今回のような使い方の場合、

関数ポインタというのは、C++言語の思想から少し外れているのです。

 

ただ単に関数を呼び出す程度であれば、C++言語には素晴らしい使い方が用意されています。

 

ちょっと長くなるので、本日はここでいったん区切ります。

 

次はC++言語でのコールバックの作り方をC++言語学びます。

 

晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ

雑談

 

C++言語でも、状態遷移を作る際には、関数ポインタは大活躍します。

したがって、C++言語の場合、関数ポインタがだめというわけではないのです。

 

 

実は、この内容。

2000年代前半のころ・・・SAIが駆け出し2年の新人の頃です。

 

携帯電話のOSが、μITronからSymbianOSに代わる際の話です。

 

お客様から、とある状態遷移の処理をC++言語で、

関数ポインタを使ってメンテナンス性の良い美しいもの(コード)を実装しろと命令されて、

当時非常に悩みました。

 

メンテナンス性を考慮したら、const配列で定義する必要があるのですが、

そうすると、ビルド時点でアドレス確定しておく必要があります。

 

が、上記の通り、クラス内にメンバー関数を配置すると、

アドレスが決定していないので、ビルドが通るわけないのです。

 

C++言語で関数ポインタを使う = アドレスが確定している必要がある。

つまり、クラス生成後でないといけない。


 

これをどうやったらクリアできるのか?

SAIは、1日中悩みました。

(当時、セキュリティエリアでインターネット禁止でしたし、

 そもそも当時はインターネットにその手の情報があまりありませんでした。)

 

そんな中、若造が悩んだ挙句に出た結論が、

ビルド時点で配置するには、staticとして関数を定義するしかない。

 

が、問題としては、C++言語の思想とはかけ離れているのですよね。

 

なぜかというと、Static関数からは、メンバ変数にアクセスできません。

ということは、クラス内の全関数と全変数がStaticになってしまいます。

 

こうなってくると、クラスにする意味が全くないのです。

 

お客さんの要望である、美しいものという内容に対して、

C++言語の思想としてはかけ離れるのです。

 

ただ、当時、それもC++言語があまり普及していない時代です。

駆け出し2年の若造が、ベースクラスをあまり使いこなしているわけもなく、

 

SAIは一人悩んだ挙句、1週間かけて3000ステップ程度の処理を作り上げました。

(ちなみに、先輩方はC言語の経験はベテランでしたが、

C++言語に関してはSAIに聞くレベルなので、質問しても期待できずです。)

 

 

1週間後、中間報告でお客さんに見せた瞬間、

static関数まみれでダメじゃないかとおしかりを受けました。

 

その後、お客さんがベースクラスについての情報を教えてくださったおかげで、

1週間かけて作り直すことができました。

 

 

というか駆け出し2年目にやらす作業じゃないと、今になって思いました。


 

 

後から知ったのですが、お客さんはSAIは若く見えるけど、そこそこベテランさんだと

勘違いされていたそうです。

 

この出来事は、良き?思い出になりました。

晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ晴れ

 

 

 

お読みくださっている、ごく少数の読者様にちょっと質問です。

 

①この記事、役になってますか?

 

 

②何気にマニアックな使い方なども色々知ってはいるのですが、

 興味ってありますか?

 

③今、コールバックの話をしていますが、

 C++でもコールバックや、関数ポインタの操作などができます。

 

 興味ありますかね?

 

 

自己啓発的にのんびり書いていますが、

もっと更新周期を短くしたほうがいいですかね?

(ゲームサイドの方が100倍閲覧数があるので、そっちに力を入れてるというのもある)

 

 

SAIとしては、一番楽しい言語はC++なのですが、

 

実際問題いちばん使われているのはC言語なのですよね。
 

そして、今の時代での需要からすると、

 

割と気を遣うC++言語を勉強するよりJavaやC#

もっと言えばPysonとかルビーの方が需要があったりして、

 

今の時代にはあってないのかもしれない。

 

 

SAIが職業としてC++言語を使っていた10年くらい前は、

そもそもC++を使えるエンジニアが少なかったので

需要はあったかもしれないけど・・・

 

 

この勉強的な日記、どうしようかなと思い始めた今日この頃です。