0

介绍

我正在做一个实验来模拟一些数字逻辑。(逻辑门。)

我有一个componentandgate继承的抽象基类。一个类port也继承自component. 类port有一个成员;PORTSTATE state.

PORTSTATE是一个枚举类,其值包括HIGHLOWHIGH_IMPEDANCEUNDEFINED等。(这只是背景信息。)

模拟通过将输入端口的状态更改为某个逻辑门来工作。门连接(使用指针)到一个类Net,该类又具有指向该网络上所有连接逻辑的指针。这允许根据需要更改其状态已更改的门的所有下游。考虑由于输入的变化而导致逻辑门的状态发生变化,使用其输出所连接的网络,可以相应地更新序列后面的任何门。

我的问题是如何使用友元函数和二元运算符(例如operator&.

问题示例

考虑一个与门,具有 1 个输出端口和 2 个输入端口。端口是代表门的类的成员,它们附有一些信息,例如它们的方向以及它们的状态。

调用一个函数来根据输入计算门的输出。该函数是门类的成员函数。例如,与门有这个函数的一个版本。

最初,我通过以下方式实现了该功能。

void Update()
{
    this->output_port.SetState(this->input_port_a & this->input_port_b);
}

重要的operator&是使用 2 个输入门的参数调用 ;input_port_ainput_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 个端口“与”在一起。端口是一个抽象概念,是一种跟踪哪些电流(或等效地施加了哪些电压)到哪些输入或输出的方法。更物理的解释是,端口是一小段电线,有一些电流流过。电流不是“HIGH”就是“LOW”,但肯定没有办法将这两个对象“与”在一起。我认为大多数工程师和物理学家可能会因为这一点而惊恐地看着这段代码。

所以“明显”的解决方法是将operator&And 门作为一个友好的函数。

然而,那些清醒的人会意识到这也是一个坏主意,因为这样就只能将&两个与门实例放在一起,这当然没有意义,也不会计算出正确的结果!(它甚至可以计算出合理的结果吗?不太可能。)

*(完全错误)

考虑;

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...
}

所以是的,这就是问题所在,我想不出解决方案。尽管在某种意义上是概念性的,但使用第一种方法并能够将两个线“与”在一起似乎是一个严重缺陷的想法。

可能 - 但不太可能 - “解决方案”

我能想到的唯一一件事就是完全放弃运算符,并在与门的Update()函数中手动编写所有内容......但是这种避免了 C++ 的优点,即你可以为这些事情编写运算符。

请注意,如果没有这样的东西PORTSTATE并且如果使用了替换bool,那么就不会有问题,因为可以简单地将 2 个布尔类型&'ed 在一起。但是,这会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&为两个重载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 操作仅适用于状态。

调用成员函数不会造成混淆并且被广泛使用。首先,这明确表明端口具有您正在与的状态(这更合乎逻辑)。其次,它保护state字段免受外部修改。

于 2014-08-10T22:48:47.223 回答