为什么cout调用父运算符<

问题描述 投票:-1回答:1

我有3个类,并且我希望每个类都以不同的方式输出到终端,我有一个节点类,它表示BDD图中的一个顶点,现在我正尝试编写代码以对它们进行逻辑运算节点。

Node类的设置如下:

class Node {

    char name;

    public:
        Node() { name = '0'; }
        Node(char c) { name = c; }

        Node(const Node& n) { name = n.name; }

        friend ostream& operator<<(ostream& stream, const Node& n);
};

ostream& operator<<(ostream& stream, const Node& n) {
    return stream << "{ Node " << n.name << " }";
}

操作员类的设置如下:

class Operation {
    public:

    Node result;

    friend std::ostream& operator<<(std::ostream& stream, const Operation& op);

    Operation() {}

    Operation(const Operation& op) { cout << "Copying " << *this << endl; }

    virtual ~Operation() { cout << "Destroying " << *this << endl; }

    virtual Node compute() { 
        cout << "Computing " << *this << endl; 
        result = Node('1');
        return result; 
    }
};

std::ostream& operator<<(std::ostream& stream, const Operation& op) { 
    return stream << "Operation { Unspecified }"; 
}


class UnaryOperation : public Operation {
    public:

    Node arg1;

    UnaryOperation(const Node& arg1) { this->arg1 = arg1; }

    UnaryOperation(const UnaryOperation& op) : Operation::Operation(op) {
        arg1 = op.arg1;
    }

    virtual ~UnaryOperation() {}

    friend ostream& operator<<(ostream& stream, const UnaryOperation& op);
};

ostream& operator<<(ostream& stream, const UnaryOperation& op) {
    return stream << "Operation { arg1: " << op.arg1 << " }";
}


class BinaryOperation : public UnaryOperation {
    public:

    Node arg2;

    BinaryOperation(const Node& arg1, const Node& arg2) : UnaryOperation(arg1) { 
        this->arg2 = arg2; 
    }

    BinaryOperation(const BinaryOperation& op) : UnaryOperation::UnaryOperation(op) {
        arg2 = op.arg2;
    }

    virtual ~BinaryOperation() {}

    friend ostream& operator<<(ostream& stream, const BinaryOperation& op);
};

ostream& operator<<(ostream& stream, const BinaryOperation& op) {
    return stream << "Operation { arg1: " << op.arg1 << ", arg2: " << op.arg2;
}

出于调试的原因,这些消息需要按原样打印出来,但是当我运行此消息时

Node apply(Operation& op) {
    cout << "Performing apply operation on " << op << endl;
    op.compute();
    return op.result;
}


int main() {
    Node a('a'), b('b');
    UnaryOperation uop(a);
    BinaryOperation bop(a, b);
    cout << uop << endl;
    cout << bop << endl;
    apply(uop);
    apply(bop);
}

我知道

Operation { arg1: { Node a } }
Operation { arg1: { Node a }, arg2: { Node b }
Performing apply operation on Operation { Unspecified }
Computing Operation { Unspecified }
Performing apply operation on Operation { Unspecified }
Computing Operation { Unspecified }
Destroying Operation { Unspecified }
Destroying Operation { Unspecified }

不用说,这对调试不是很有帮助。

为什么这样做,我该如何解决?

c++ inheritance operator-overloading virtual friend-function
1个回答
1
投票

朋友功能不是虚拟的。根据第二个参数的类型选择它。

在此功能中

Node apply(Operation& op) {
    cout << "Performing apply operation on " << op << endl;
    op.compute();
    return op.result;
}

参数的类型为Operation &。因此,在此声明中

cout << "Performing apply operation on " << op << endl;

类型为Operation &的对象称为朋友功能。

您可以通过以下演示程序中所示的以下方式使朋友功能“虚拟”。

#include <iostream>

class Operation 
{
public: 
    virtual ~Operation() = default;

private:    
    virtual std::ostream & out( std::ostream &os = std::cout ) const
    {
        return os << "This is an Operation"; 
    }

    friend std::ostream& operator <<( std::ostream &stream, const Operation &op ) 
    { 
        return op.out( stream ); 
    }
};

class UnaryOperation : public Operation 
{
    std::ostream & out( std::ostream &os = std::cout ) const override
    {
        return os << "This is an Unary Operation";
    }

    friend std::ostream& operator <<( std::ostream &stream, const UnaryOperation &op ) 
    { 
        return op.out( stream ); 
    }
};

class BinaryOperation : public UnaryOperation 
{
    std::ostream & out( std::ostream &os = std::cout ) const override
    {
        return os << "This is a Binary Operation";
    }

    friend std::ostream& operator <<( std::ostream& stream, const BinaryOperation &op ) 
    { 
        return op.out( stream ); 
    }
};

void f( const Operation &op )
{
    std::cout << op << '\n';
}

int main() 
{
    BinaryOperation bop;

    f( bop );

    return 0;
}

其输出为

This is a Binary Operation
© www.soinside.com 2019 - 2024. All rights reserved.