0

序章

デジタルロジックをシミュレートする実験に取り組んでいます。(論理ゲート。)

componentクラスがandgate継承する抽象基本クラスがあります。クラスportも から継承しcomponentます。クラスportにはメンバーがあります。PORTSTATE state.

PORTSTATEHIGHLOWHIGH_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 つしかないという問題も発生します。未定義状態やハイインピーダンス状態などを扱えるものはありません。

だから私は立ち往生していて、アイデアがありません。

4

1 に答える 1

1

operator&for two をオーバーロードしPORTSTATEます。その問題を解消しながらUNDEFINED、最後のフォームが機能するようになります。

PORTSTATE operator&(const PORTSTATE& a, const PORTSTATE& b)
{
    ...
}

void Update()
{
    return input_a.state() & input_b.state(); // input_* is of type port
                            // state() is a member function returning a bool
}

私にとっては、AND 演算は状態のみで動作するため、これが最も正しい方法です。

メンバー関数の呼び出しは混乱を招くことはなく、広く使用されています。まず、これにより、ポートがANDしている状態を持っていることが明確になります(これはより論理的です)。state第二に、フィールドを外部からの変更から保護します。

于 2014-08-10T22:48:47.223 に答える