3

im trying to construct a circuit simulator and running into some erros with inherritance. I think im just confused because ive been staring at it for too long, so would appreciate some help.

error message:

prep_3.cpp: In constructor 'wire::wire(bool&, binary_gate&)':
prep_3.cpp:147:70: error: no matching function for call to 'binary_gate::binary_gate()'
   wire(bool &from, binary_gate &to) : bit_output(from), gate_input(to) {
                                                                      ^

Class causing problems:

class wire{
    public : 
        wire(binary_gate &from, binary_gate &to) : gate_output(from), gate_input(to) {
            //want to pass output of from into to.
            //therefore must set_next_bit of to taking the input as the output of from
            to.set_next_bit(from.get_output()); 
        }

        wire(bool &from, binary_gate &to) : bit_output(from), gate_input(to) {
            to.set_next_bit(from); 
        }

    private : 
        binary_gate gate_output, gate_input; 
        bool bit_output, bit_input; 
}; 

Binary gate class:

class binary_gate : public logic_element{
    public : 
    binary_gate(string s) : logic_element(s), bitA_status(false), bitB_status(false){}; 

    bool get_bitA(){
        if(!bitA_status){
            cout << "A hasn't been assigned yet! please set it : " ; 
            cin >> bitA; 
            bitA_status = true; 
        }
        return bitA; 
    }

    bool get_bitB(){
        if(!bitB_status){
            cout << "B hasn't been assigned yet! please set it : " ; 
            cin >> bitB; 
            bitB_status = true; 
        }
        return bitB; 
    }

    void set_bitA(bool val){
        bitA = val; 
        bitA_status = true; 
    }

    void set_bitB(bool val){
        bitB = val; 
        bitB_status = true; 
    }

    bool get_statusA(){
        return bitA_status; 
    }


    bool get_statusB(){
        return bitB_status; 
    }

    virtual void set_next_bit(bool from_bit){ 
        if(!bitA_status){ 
            bitA = from_bit;
            this->bitA_status = true; 
        }
        else if(!bitB_status){ 
            bitB = from_bit; 
            this->bitB_status = true;           
        }
    }

    protected: 
        bool bitA;
        bool bitB; 
        bool bitA_status; // true = taken, false = empty
        bool bitB_status; // true = taken, false = empty

};

Keep in mind the code was working before I added the second constructor for wire which takes in a bool and a binary_gate.

I've deduced that the error comes from the second constructor in the wire class. This puzzles me as its very similar to the first constructor, all im doing is passing a bool input which arguably should be more simple to code!

Thanks

2 Answers2

2

Your wire class has 4 member variables. Each one of these needs to be constructed during construction of a wire.

wire(bool &from, binary_gate &to) : bit_output(from), gate_input(to)

gives instructions on how to construct bit_output and gate_input, but not bit_input and gate_output. Default constructors are called for these. But you don't have a default constructor for gate_input which is of type binary_gate.

Declare a public default constructor for binary_gate in the binary_gate class

binary_gate() = default;

or

binary_gate() : ...initialization list... {}

if you want the default binary_gate to have other specific values.

JohnFilleau
  • 4,045
  • 1
  • 15
  • 22
1

The problem is that your second constructor for the wire class:

wire(bool &from, binary_gate &to) : bit_output(from), gate_input(to) {
    to.set_next_bit(from); 
}

is required to call the default constructor for binary_gate, for the gate_output member ... and you haven't provided a default constructor (i.e. one with no argument). This is because, once you provide a constructor with a different signature (as binary_gate(string s)), the compiler no longer provides an implicit default. From cppreference (bolding mine):

If no user-declared constructors of any kind are provided for a class type (struct, class, or union), the compiler will always declare a default constructor as an inline public member of its class.

However, your other constructor for the wire class uses the copy constructor for both gate_input and gate_output, and the compiler does provide a default for this. Again, from cppreference:

If no user-defined copy constructors are provided for a class type (struct, class, or union), the compiler will always declare a copy constructor as a non-explicit inline public member of its class.

To get round this, you need to explicitly set a default constructor (with no argument); the simplest way is as follows:

class binary_gate : public logic_element{
    public : 
    binary_gate(string s) : logic_element(s), bitA_status(false), bitB_status(false){}; 
    binary_gate() = default; // Provide an *explicit* default constructor.
    //...

Feel free to ask for further clarification and/or explanation.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • Thanks for the speedy response. turns out I didn't know what the copy constructor was, so i suppose my real confusion in the first place should have been why the first constructor worked at all! your response has cleared things up a bunch. Thanks again. –  Feb 25 '20 at 18:13