MASATOの開発日記


前の開発日記 次の開発日記 一覧

2002/02/22

この日記のために利用しているXMLとXSLは結構便利です。 どのようなフォーマットのXMLにするか決め、htmlへの変換用XSLを決めてしまうと あとはさくさく書くだけです。一覧表示用XSLを作ってしまえば 話題一覧も簡単に作れます。しかし、XSLを作り上げるまでが大変です。 この日記を書き始めた後、公開するのが何ヶ月か遅れたのは、 ここらへんを固めていたからです。
しかし、その価値はあったと思います。 昔の開発日記はhtmlで書いていましたので、見栄えを変更するのが凄い大変でしたが、 今はさらりとXSLを書き、XSLT(msxsl)を用いて変換して終わりです。
msxslは、MicroSoftのXSLTなのですが、 ShiftJIS対応で、実行ファイルとしてしっかりと配布されているフリーのXSLTなんて、 現状ではこれだけではないでしょうか。 こういうものをしっかりと作ってしまうあたり、MicroSoft恐るべし・・・。

protected継承とprivate継承

C++には、protected継承やprivate継承がありますが、 果たしてこれは何に使うのだろうか、と考えてみました。
普通、何かクラスを派生させて新しいクラスを定義するときは、 必ずといっていいほどpublic継承が使われます。デフォルトでprivateなのが不思議なくらいです。
protected/private継承を用いると、オブジェクト指向の三大要素の一つである多態性が失われます。
例えばクラスBaseをprotected継承してクラスHogeを定義したとしますと、 外から見たとき、Baseの関数は1つも呼べません。 Hoge*型の変数をBase*にキャストすることも出来ません。 つまり外から見たときは、HogeはBaseと関わりの無いクラスにしか見えないわけです。 この点は、HogeクラスにBaseクラスのインスタンスをメンバ変数として持たせたときと同様です。

そうです。つまり、protected/private継承は、基底クラスをメンバ変数として持たせることにより 代用できる場合も多いのです。では、双方の方法の利点を考えてみますと・・・

protected/private継承の利点は、基底クラスのprotectedメンバ関数が利用できることです。 ですので、基底クラスのprotectedメンバ関数を使いたいけれど、 外から見たときは基底クラスに見えて欲しくない、というときはprotected/private継承を利用しましょう。

逆に、メンバ変数として持つ方の利点は、protectedメンバ関数を利用できないことです。 protectedメンバ関数は、良く分からないまま派生して使うと危険な場合があります。 比較的安全なpublic関数のみを利用し、protected関数は間違えて使ったりしないようにしたいと 思ったら、メンバ変数として保持するのが正解でしょう。

というわけで、protected/private継承にも使い道が見つかりました。 どんなものにもなんらかの使い道はあるものです。

自端末上の全てのIPアドレス及びネットマスクを取得する方法

環境Visual C++ 6.0

前回の続きとなります、全てのIPアドレスの取得方法です。 正確には、全てのネットワークインターフェースのIPと、ネットマスクと、 ブロードキャストアドレスが取得できます。

まずはヘッダファイルをインクルードしましょう。

#include <winsock2.h>

MFCの場合は、afxsock.hをインクルードするより前にこれをインクルードしましょう。

IP取得部分はこのようになります。

// ●取得するIPの最大数が20。必要に応じて変えましょう。●
INTERFACE_INFO info[20];
// ●とりあえずソケットを作成します。UDPであることに深い意味はありません。●
SOCKET hSocket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0);
DWORD returned;
WSAIoctl(hSocket, SIO_GET_INTERFACE_LIST, NULL, 0, info, sizeof(info), &returned, NULL, NULL);
UINT n = returned / sizeof(info[0]);
for (UINT i = 0; i < n; i++){
  if ((info[i].iiFlags & IFF_UP) == 0){
    // ●稼動状態では無い。●
    continue;
  }
  if ((infp[i].iiFlags & IFF_LOOPBACK) != 0){
    // ●ループバックアドレスである。●
    continue;
  }
  IN_ADDR address = iinfo[i].iiAddress.AddressIn.sin_addr;
  IN_ADDR broadcast = iinfo[i].iiBroadcastAddress.AddressIn.sin_addr;
  IN_ADDR netmask = iinfo[i].iiNetmask.AddressIn.sin_addr;
  // ●ここでaddressとbroadcastとnetmaskを使っていろいろする。●
}
// ●ソケットにはもう用が無い。●
closesocket(hSocket);

ループバックアドレスも求まりますので、必要に応じてうまくお使い下さい。
iiFlagは、ブロードキャストをサポートしていたらIFF_BROADCASTが立ち、 マルチキャストをサポートしていたらIFF_MULTICASTが立ちます。 これも必要に応じてお使い下さい。

前の開発日記 次の開発日記 一覧