Visual Basic 2005 ここが便利!

第6回 演算子のオーバーロードで独自の型も‘+’で足し算!

株式会社ピーデー 川俣 晶
2005/06/29

Visual Studio 2005や.NET Framework 2.0の登場とともに、プログラミング言語であるVisual Basic .NETも「Visual Basic 2005」へとバージョン・アップする。この新しいVisual Basicには、言語仕様の面でも統合開発環境の面でも、プログラミングを楽にする新機能が満載だ。本連載ではその中でも特に注目すべき便利な機能を1つずつピックアップしながら紹介していく。

演算子のオーバーロードとは?

Back Issue
1
“My”はクラスの海からVBプログラマを救う!?
2 型指定されたコレクションを実現するジェネリック
3 自動生成コードを分離、ソースをすっきりパーシャル・クラス
4 Background Workerで夢のマルチスレッドがついに!
5 Usingステートメントで簡単、確実にファイルをクローズ

 Visual Basic 2005では、計算に使用する‘+’や‘−’といった演算子の機能を再定義することができるようになる。これを「演算子のオーバーロード」という。つまり、計算式の中で‘+’や‘−’といった記号を書いたときに、実際に何を行うかを、プログラマが自由に指定することができるのである。

 例えば、+記号を使ったときに引き算を行い、−記号を使ったときには足し算を行うようなひねくれた定義を書くことも不可能ではない。もちろん、不可能ではないというだけで、やらない方がよいのはいうまでもない。

 さて、この機能に関して最も問題になるのは、なぜこのような機能が必要なのかという点だろう。恐らく、大半のVBプログラマの皆さんは、何に使う機能か首をかしげていると思う。+記号は足し算であり、それで決まっている。その機能を定義できたとしても、何のメリットもないように思える。実際、この機能のありがたみをかみしめるための例題の選定は、とても難しい。

 例えば、演算子のオーバーロードといえば、複素数同士の演算をサンプルにすることが多く、実際にVisual Basic 2005の資料でも複素数を例題にした解説がある。しかし、複素数といわれても何のことか分からないという読者が多数派だろう。そもそも一般のパソコン利用者や業務システムの開発者が複素数という特殊な数を必要とする場面はめったにないはずだ。

演算子のオーバーロードが欲しくなる事例

 そこで、今回はない知恵を絞って、少しは分かりやすい事例を、と考えてみた。題して「本体価格と消費税を別々に集計してみよう」である。

 より具体的には次のようになる。以下のような商品を購入したが、本体価格と消費税はそれぞれ独立して別個に集計したいとしよう。

  • アメ(本体価格100円、消費税5円)
  • チョコ(本体価格200円、消費税10円)
  • ガム(本体価格300円、消費税15円)

 まずは、演算子のオーバーロードを使わないで書いてみた(以下のコードはVisual Basic 2005 Express Beta 2にてコンソール・アプリケーションとして作成。以降も同じ)。このプログラムでは分かりやすいように変数名に日本語を使用している(もちろんコンパイル可能)。

Module Module1
  Sub Main()
    Dim アメ本体価格 As Integer = 100
    Dim アメ消費税 As Integer = 5

    Dim チョコ本体価格 As Integer = 200
    Dim チョコ消費税 As Integer = 10

    Dim ガム本体価格 As Integer = 300
    Dim ガム消費税 As Integer = 15

    Dim 合計本体価格 As Integer = _
      アメ本体価格 + チョコ本体価格 + ガム本体価格

    Dim 合計消費税 As Integer = _
      アメ消費税 + ガム消費税 ' チョコ消費税書き忘れ

    System.Console.WriteLine( _
      "本体価格合計{0}円 + 消費税合計{1}円 = {2}円", _
      合計本体価格, 合計消費税, 合計本体価格 + 合計消費税)
  End Sub
End Module
3つの商品の本体価格と消費税を別に集計するサンプル・プログラム
このサンプル・プログラムは現行のVisual Studio .NET 2003でも実行可能。

 これを実行すると以下のような結果になる。

本体価格合計600円 + 消費税合計20円 = 620円

 さて、この結果はもちろん間違っている。合計消費税の計算で、チョコ消費税の加算を書き忘れているためである。そのため、合計本体価格は3個分の合計であるのに、合計消費税は2個分の合計でしかない。非常に単純なミスではあるが、この種のミスはどこかでふっと入り込み、人間が人間である以上、根絶することは不可能である。努力や根性で解決できるものではない。

 しかし、解決策がないわけではない。本体価格と消費税を別々に足し合わせるから食い違いが発生するのである。これを、常に同時に足し合わせるような構造に変更してしまえば、食い違いは絶対に発生しない。つまり、本体価格と消費税が常にワンセットで足されれば、足す回数の食い違いは発生しようがないのだ。

Visual Basic 2005における演算子のオーバーロード

 以上のような状況に対応するため、演算子のオーバーロードはうってつけの機能といえる。以下に、演算子のオーバーロードを使って書き直した例を紹介する。

Class 消費税付価格
  Public ReadOnly 価格 As Integer
  Public ReadOnly 消費税 As Integer

  Public Sub New(ByVal 価格 As Integer, ByVal 消費税 As Integer)
    Me.価格 = 価格
    Me.消費税 = 消費税
  End Sub

  Public Shared Operator +(ByVal 価格1 As 消費税付価格, ByVal 価格2 As 消費税付価格) As 消費税付価格
    Return New 消費税付価格(価格1.価格 + 価格2.価格, 価格1.消費税 + 価格2.消費税)
  End Operator
End Class

Module Module1

  Sub Main()
    Dim アメ As New 消費税付価格(100, 5)
    Dim チョコ As New 消費税付価格(200, 10)
    Dim ガム As New 消費税付価格(300, 15)

    Dim 合計 As 消費税付価格 = アメ + チョコ + ガム
    Console.WriteLine(  _
      "本体価格合計{0}円 + 消費税合計{1}円 = {2}円", _
      合計.価格, 合計.消費税, 合計.価格 + 合計.消費税)
  End Sub

End Module
演算子のオーバーロードを使用したサンプル・プログラム
Visual Basic 2005では、Operatorキーワードにより演算子(このプログラムでは+演算子)をオーバーロードして、独自の演算処理を記述できる。

 これを実行すると以下のような結果になる。

本体価格合計600円 + 消費税合計30円 = 630円

 まず注目すべきは、以下の2行が1行にまとまってしまったことである。

Dim 合計本体価格 As Integer = アメ本体価格 + チョコ本体価格 + ガム本体価格
Dim 合計消費税 As Integer = アメ消費税 + チョコ消費税 + ガム消費税

 これが以下の1行になってしまった。

Dim 合計 As 消費税付価格 = アメ + チョコ + ガム

 ここで、アメ、チョコ、ガムは、消費税付価格という型(クラス)の変数である。このクラスは「Public Shared Operator +」で始まる定義により、+演算子をオーバーロードしている。

 具体的には、消費税付価格型の値同士を+演算子で足し算した結果を、同じく消費税付価格型で返すという処理についての定義を含んでいる。これは、消費税付価格型同士の足し算が、両者の価格と消費税を足した値を持つ新しい消費税付価格型のインスタンスになる、という定義だ。

 内容が分かりにくく、完全に理解できない読者もいると思うが気に病む必要はない。この記事は、技術の「紹介」のために書かれたものであって、入門記事ではない。内容を完全に理解するのは、Visual Basic 2005のリリース後で何ら問題はない。ここでは、ムードだけをつかみ取っていただきたい。

 さて、もう一度「アメ + チョコ + ガム」という数式を見ていただきたい。この式は、まさに足し算を意図したものであって、+演算子を使うことで分かりやすくなった式だといえる。

 また、入力する文字数も少なく、結果的にソース・コードが短くなる。このようなサンプル・プログラムでは、演算子のオーバーロードを定義するための行数が多いため、コードが短くなるという実感は少ないかもしれないが、それなりの実用システムの規模で利用すれば、定義が全体に占める割合など微々たるものであり、ソース・コード全体の行数を減らす効能を期待してもよいだろう。

 そして何より、ペアになった数値が必ずペアで足されることが保証されているので、バグも入り込みにくいのである。End of Article

 
インデックス・ページヘ  「Visual Basic 2005 ここが便利!」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH