トップ «前の日記(2004-06-12) 最新 次の日記(2004-06-14)» 編集

日々の破片

著作一覧

2004-06-13

_ C++にinterfaceが無いのはなぜか?

多重継承が可能だから、別にinterfaceはいらない。

下の例だと、Number(値が返せて、加算が可能)、Character(コードを返せる)は、単なるインターフェイスで、実装を継承するために用意したわけではない。

#include <stdio.h>
 
class Number {
public:
    virtual int value() = 0;
    virtual int add(int x) = 0;
};
 
class Character {
public:
    virtual int code() = 0;
};
 
class A : public Character {
public:
    int code() {
	return 0x41;
    }
};
 
class HexA : public Number, public A {
public:
    int value() {
	return 0x0a;
    }
    int add(int x) {
	return value() + x;
    }
};
 
class One : public Number {
public:
    int value() {
	return 1;
    }
    int add(int x) {
	return x + 1;
    }
};
 
void printNumber(Number& n) {
    printf("number:  value=%d\n", n.value());
    printf("number: add(8)=%d\n", n.add(8));
}
 
void printCharacter(Character& c) {
    printf("Character:  code=0x%X\n", c.code());
}
 
int main(int argc, char* argv[]) {
    A a;
    HexA ha;
    One one;
 
    printCharacter(a);
    printCharacter(ha);
    printNumber(ha);
    printNumber(one);
 
    return 0;
}

実行するとこんなふうになる。

C:\Home\arton>cl test.cpp
cl test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
 
test.cpp
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
 
/out:test.exe 
test.obj 
 
C:\Home\arton>test
test
Character:  code=0x41
Character:  code=0x41
number:  value=10
number: add(8)=18
number:  value=1
number: add(8)=9
 
C:\Home\arton>

この例では、HexAは、NumberインターフェイスとCharacterインターフェイスを両方実装している(かつ、Characterインターフェイスを実装したクラスAの実装を借用している)。

多重継承を正しく扱うためには、万能のObjectのような型を周到にデザインから排除しなければならない。そうでなければ、菱形継承の問題が顔を表すことになる。

また、多重継承をうまく利用するためにはデータを排除することが重要なのではないか?と語るスコットEffective C++マイヤー。

それでは、実体を伴わないメソッドの集合の定義としてinterface(起源はOMG IDLなのかな?)を採用したJavaには菱形(ダイアモンド)継承問題はないのか? というとダイアモンドは永遠にということも。

_ C#

ダイアモンドは永遠にを読んでいて??となったが、Javaってそうなのか。C#だと全然OKなんだけど。

public interface HonestClass {
    bool turnInLostMoney();
}
 
public interface DishonestClass {
    bool turnInLostMoney();
}
 
public class Citizen : HonestClass, DishonestClass {
    bool HonestClass.turnInLostMoney() {
	return true;
    }
 
    bool DishonestClass.turnInLostMoney() {
	return false;
    }
 
    public static void Main() {
	Citizen c = new Citizen();
	System.Console.WriteLine("Do you turn in lost money ?");
	System.Console.WriteLine(((HonestClass)c).turnInLostMoney());
	System.Console.WriteLine(((DishonestClass)c).turnInLostMoney());    
    }
}

実行すると

C:\Home\arton>csc Citizen.cs
csc Citizen.cs
Microsoft(R) Visual C# .NET Compiler version 7.10.3052.4
for Microsoft(R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.
 
C:\Home\arton>citizen
citizen
Do you turn in lost money ?
True
False
 
C:\Home\arton>

変なところで不便な善良な市民には住みにくい仕様だな。

_ ホンダで点検

貰った(ねだったとも言う)。

結構、可愛い。

_ 無理が通れば道理引っ込む

「とんでもない欠陥が見つかりました。至急リコールを」

「いらんいらん。実害は無いから」

「な、何を根拠に?」

「だってリコールしたらブランドイメージにキズがつくっていう実害があるでしょ? それに対してリコールしなければ当然その実害は無い。実害が無いんだからこのままで良い。シュアロジカリー」

「そりゃ無理です。至急リコールを」

「無理だと思ったら何も始まらない。我が社のチャレンジが日本を変える。やらなきゃ!」

「そりゃ人死にが出たら変わるでしょうが、それでは手遅れってものです。リコール無しで済ますのは無理です」

「『無理だ』は我が社の禁句にせえへんか?」

「我が社が禁句にしたところで、実害に合うのは我が社以外の人なんですよ」

「まぁまぁ、知らぬが仏と言うではないか」

「そりゃ確かに知らないうちに仏になっちゃうでしょうけど、生き残った人にはバレバレですよ」

「そっか生き残りが出ると言うことは、シェアが低いのが問題ということだな。目指せナンバーワン!」

「無理ですよ」

「無理だと思ったら何も始まらない。我が社のチャレンジが日本を変える。やらなきゃ!」

「この会社で仕事を続けるのは無理だな……」


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|

ジェズイットを見習え