序章
デジタルロジックをシミュレートする実験に取り組んでいます。(論理ゲート。)
component
クラスがandgate
継承する抽象基本クラスがあります。クラスport
も から継承しcomponent
ます。クラスport
にはメンバーがあります。PORTSTATE state
.
PORTSTATE
HIGH
、LOW
、HIGH_IMPEDANCE
、などの値を持つ列挙型クラスですUNDEFINED
(これは単なる背景情報です)。
シミュレーションは、入力ポートの状態を論理ゲートに変更することによって機能します。ゲートは (ポインターを使用して) クラスNet
に接続され、そのクラスはそのネットワーク上のすべての接続されたロジックへのポインターを持ちます。これにより、状態が変更されたゲートの下流にあるすべてのゲートを必要に応じて変更できます。入力の変化によって変化する論理ゲートの状態を考えてみましょう。その出力が接続されているネットワークを使用すると、シーケンスのさらに下にあるゲートをそれに応じて更新できます。
私の質問は、フレンド関数とoperator&
.
問題の例
1 つの出力ポートと 2 つの入力ポートを持つ And ゲートを考えてみましょう。ポートはゲートを表すクラスのメンバーであり、方向や状態などの情報が関連付けられています。
入力からゲートの出力を計算する関数が呼び出されます。この関数は、gate クラスのメンバー関数です。たとえば、And ゲートには、この関数のバージョンがあります。
最初に、次の方法で関数を実装しました。
void Update()
{
this->output_port.SetState(this->input_port_a & this->input_port_b);
}
重要なのoperator&
は、 が 2 つの入力ゲートの引数で呼び出されることです。input_port_a
そしてinput_port_b
引数として。
次に、ポート クラスで、この演算子を実装しました。
friend const port& operator&(const port& left, const port& right)
{
if((left.state == PORTSTATE::HIGH) && (right.state == PORTSTATE::HIGH))
{
return PORTSTATE::HIGH;
}
else if( // These are the 3 options for definitive low
((left.portstate == PORTSTATE::LOW) && (right.portstate == PORTSTATE::HIGH))
|| ((left.portstate == PORTSTATE::LOW) && (right.portstate == PORTSTATE::LOW))
|| ((left.portstate == PORTSTATE::HIGH) && (right.portstate == PORTSTATE::LOW))
)
{
return PORTSTATE::LOW;
}
else
{
return PORTSTATE::UNDEFINED; // Anything else is not defined
}
}
しかし、これには深刻な問題があります。2 つのポートを一緒に「AND」することはできません。ポートは抽象的な概念であり、どの入力または出力にどのような電流が流れているか (または同等にどのような電圧が印加されているか) を追跡する方法です。より物理的な解釈は、ポートが短い長さのワイヤであり、電流が流れているというものです。電流は「HIGH」または「LOW」ですが、これら 2 つのオブジェクトを「AND」する方法はありません。ほとんどのエンジニアや物理学者は、おそらくこの点のために、このコードを恐ろしく見るだろうと思います。
したがって、「明らかな」修正はoperator&
、 And ゲートの内側をフレンドリーな関数として配置することです。
ただし、目を覚ましている人は、これも悪い考えであることに気付くでしょう*。なぜなら&
、And ゲートの 2 つのインスタンスのみが一緒に可能であり、これは確かに意味がなく、正しい結果を計算しません! (理にかなった結果を計算することさえできるでしょうか? 可能性は低いです。)
*(完全に間違っています)
検討;
andgate and_gate_1, and_gate_2;
// Setup the inputs, outputs, connections, networks
// When stepping through the simulation, we end up with something like this:
and_gate_1.Update();
// Which calls a function like this:
const andgate& operator&(const andgate& left, const andgate& right)
{
// How would you even implement this? It makes no sense...
}
そうです、これが問題であり、解決策が思いつきません。ある意味では概念的ではありますが、最初のアプローチを使用して 2 つのワイヤのビットを一緒に「AND」できるという考えには、深刻な欠陥があるように思えます。
可能 - しかし、あまり可能ではない - 「解決策」
私が考えることができる唯一のことは、演算子を完全に省き、And ゲートのUpdate()
関数内ですべてを手動でプログラムすることです...しかし、この種のことは、C++ の優れた点、つまり、そのようなもののための演算子を作成できることを回避します。
そのようなものがなくPORTSTATE
、代わりbool
に使用された場合は、2 つのブール型を単純に組み合わせることができるため、問題はないことに注意してください&
。ただし、これはこのUpdate()
ようなものに変更され、これもあまり良くありません。(メモ メンバー アクセスはパブリックです。)
void Update()
{
return (input_a.state) & (input)b.state); // input_* is of type port, state is a bool
}
間違いなく、データを保護する方が良いでしょう: (しかし、関数呼び出しのせいで「見た目」が悪くなるのではないでしょうか?)
void Update()
{
return (input_a.state()) & (input)b.state()); // input_* is of type port
// state() is a member function returning a bool
}
これにより、既存の状態が 2 つしかないという問題も発生します。未定義状態やハイインピーダンス状態などを扱えるものはありません。
だから私は立ち往生していて、アイデアがありません。