Gabi B
Gabi B

Reputation: 11

Why doesn't this code work? I got an error: incomplete type or does not name a type

Why don't forward declarations work? I didn't implement any pointers in the constructor so it should work. So why doesn't it?

#include<iostream>
using namespace std;

class foo;
/*if i use this 2 lines i got first error if not the second one. How do i solve this? */
class on;
class off;

class state{
protected:    
    foo *_context;
public:
    virtual void t_on() = 0;
    virtual void t_off() = 0;
    virtual void handle() = 0;
};

class foo{
    private:
        state *_current;
    public:
    void setState( state* st){
        _current = st;
    }
    void on(){
        _current->t_on();
    }
    void off(){
        _current->t_off();
    }

    void handle(){
        _current->handle();
    }
};
class off:public state{
      void t_on(){
        std::cout << "on\n";
    }
    void t_off(){
        std::cout << "cant is off\n";
    }
     void handle(){
        std::cout << "handle to on";
        _context->setState( new on );
    }
};
class on:public state{
    public:
    void t_on(){
        std::cout << "cant is on\n";
    }
    void t_off(){
        std::cout << "off\n";
    }
    void handle(){
        std::cout << "handle to off";
        _context->setState( new off );
    }
};


int main ()
{
    foo asd;
    asd.setState(new on);
    asd.on();
    asd.off();
    return 0;
}

I tried to implement state pattern in c++ but I can't understand how these pointers work.

with

class on; 
class off; 

this is happening when i try to use forward declaration.

main.cpp: In member function 'virtual void off::handle()':
main.cpp:45:28: error: invalid use of incomplete type 'class on'
    _context->setState( new on );
                            ^
main.cpp:6:8: note: forward declaration of 'class on'
  class on;

If I got this error for class on then why does class off work?

without

and this when I'm now

main.cpp: In member function 'virtual void off::handle()':
main.cpp:53:28: error: 'on' does not name a type
    _context->setState( new on );
                            ^

Upvotes: 1

Views: 66

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409356

To create an instance of a class (like you do with new on) you need the full definition. But at that point in the source code you don't have the full definition of the class on, only the forward declaration.

The common solution is to split the class into the class definition, and the member function definitions.

Like e.g.

// Define the class
class off:public state{
public:
    void t_on();
    void t_off();
    void handle();
};

// Define the class and its member functions
class on:public state{
    public:
    void t_on(){
        std::cout << "cant is on\n";
    }
    void t_off(){
        std::cout << "off\n";
    }
    void handle(){
        std::cout << "handle to off";
        _context->setState( new off );  // Can use off because it's fully defined
    }
};

// Define the member function of the class off
inline void off::t_on(){
    std::cout << "on\n";
}

inline void off::t_off(){
    std::cout << "cant is off\n";
}

inline void off::handle(){
    std::cout << "handle to on";
    _context->setState( new on );  // Can use on because it's fully defined
}

With the above code, when the class on and its member functions are defined, the class off will be fully defined. Then later when defining the member functions of off then you will also have the full definition of the on class.

Upvotes: 2

Related Questions