CodeGuru Forums -
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic Newsletters VB Forums Developer.com


Newest CodeGuru.com Articles:

  • Deploying Windows Server 2008 with System Center
  • Remote Desktop Protocol Performance Improvements in Windows Server 2008 R2 and Windows 7
  • The Microsoft Dynamics CRM Security Model
  • SQL Server Modeling Services with Microsoft Visual Studio 2010 Beta 2

  • Search CodeGuru:
     



    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > C++ (Non Visual C++ Issues)
    FAQ Members List Calendar Search Today's Posts Mark Forums Read

    C++ (Non Visual C++ Issues) Ask or answer C and C++ questions not related to Visual C++. This includes Console programming, Linux programming, or general ANSI C++.

    Reply
     
    Thread Tools Search this Thread Rate Thread Display Modes
      #1    
    Old November 24th, 2009, 08:05 PM
    robione robione is offline
    Junior Member
     
    Join Date: Jan 2009
    Posts: 20
    robione is an unknown quantity at this point (<10)
    Using an undefined class?

    I'm probably going a bit overboard in writing some neural network code as far as OOP goes but I'd like to make it work if possible. The problem I am having is that I have defined classes: CNeuron, CGanglion (a layer in the network), CNetwork, and CLink (a graph edge.... a link from one neuron to another)

    In CLink.h I have "class CNeuron;" before it's definition as one of the attributes is a pointer to a neuron. This works out okay. CNeuron.h includes Clink.h, but in CNeuron.h I have a method that uses CGanglion. So I placed "class CGanglion;" prior to my definition of CNeuron.... but now I get an error. If I place this in CLink.h instead I get an error.... it seems wherever I place it I get an error.

    D:\Visual Studio Projects\ann\Neuron.cpp(41) : error C2027: use of undefined type 'CGanglion'

    Stuff like this makes me still feel like a noob. There must be a solution. Thanks for any help.

    Code:
    /*************************************/
    //CLINK.H
    
    #include <stdlib.h>
    #include <time.h>
    
    class CNeuron;
    
    class CLink  
    {
    public:
    	CLink() {::memset(this,0,sizeof(*this));}
    	~CLink() {}
    
    	double dWeight;
    	CNeuron *pNeuron;
    };
    
    /*************************************/
    //CNEURON.H
    
    #include <vector>
    #include <cmath>
    #include "Link.h"
    using namespace std;
    
    namespace afunc {
    	double identity(double x);
    	double step(double x);
    	double bipolar(double x);
    	double sigmoid(double x);
    	double bisigmoid(double x);
    }
    
    class CGanglion;
    
    class CNeuron  
    {
    public:
    	void Attach(class CGanglion *pLayer);
    	void Fire(void);
    	CNeuron();
    	virtual ~CNeuron();
    
    	double dSummator;
    	double (*pfActivation)(double);
    	vector<CLink> vOutput;
    private:
    	void Repolarize(void) {dSummator = 0.;}
    };
    
    /*************************************/
    //CGANGLION.H
    
    #include "Neuron.h"
    
    class CGanglion  
    {
    public:
    	void Add(int n,bool b);
    	CGanglion();
    	virtual ~CGanglion();
    
    	vector<CNeuron> vNeurons;
    
    };
    I don't understand why it works for one file but not the other.
    Reply With Quote
      #2    
    Old November 24th, 2009, 08:33 PM
    VladimirF VladimirF is offline
    Elite Member
    Power Poster
     
    Join Date: Aug 2000
    Location: Del Mar, California, USA
    Posts: 4,558
    VladimirF has much to be proud of (1500+) VladimirF has much to be proud of (1500+) VladimirF has much to be proud of (1500+) VladimirF has much to be proud of (1500+) VladimirF has much to be proud of (1500+) VladimirF has much to be proud of (1500+) VladimirF has much to be proud of (1500+) VladimirF has much to be proud of (1500+) VladimirF has much to be proud of (1500+) VladimirF has much to be proud of (1500+) VladimirF has much to be proud of (1500+)
    Re: Using an undefined class?

    Quote:
    Originally Posted by robione View Post
    D:\Visual Studio Projects\ann\Neuron.cpp(41) : error C2027: use of undefined type 'CGanglion'
    Looks like you only have a forward declaration of your class 'CGanglion' in Neuron.cpp.
    While it was enough for its header file, you need to include CGanglion.h in your implemetation file.
    __________________
    Vlad - MS MVP [2007, 2008, 2009] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinViewer - an integrated GDI objects viewer for Visual C++ Debugger, and more...
    Reply With Quote
      #3    
    Old November 24th, 2009, 08:34 PM
    Kheun Kheun is offline
    Elite Member
     
    Join Date: Oct 2002
    Location: Singapore
    Posts: 3,128
    Kheun is a name known to all (1000+) Kheun is a name known to all (1000+) Kheun is a name known to all (1000+) Kheun is a name known to all (1000+) Kheun is a name known to all (1000+) Kheun is a name known to all (1000+) Kheun is a name known to all (1000+) Kheun is a name known to all (1000+)
    Re: Using an undefined class?

    There's nothing wrong in writing neutral network code in OOP. Your header file seem okay except for the function signature for CNeuron::Attach(). There is no need to use the class keyword for pLayer pointer since that you have already forward declared CGanglion.

    If you can show the CNeuron.cpp file, we should be able to spot what is wrong.
    __________________
    quoted from C++ Coding Standards:

    KISS (Keep It Simple Software):
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.

    Avoid magic number:
    Programming isn't magic, so don't incant it.
    Reply With Quote
      #4    
    Old November 24th, 2009, 08:43 PM
    Russco Russco is offline
    Member
     
    Join Date: Nov 2008
    Location: England
    Posts: 478
    Russco has a spectacular aura about (150+) Russco has a spectacular aura about (150+)
    Re: Using an undefined class?

    The error is pointing at a file you didn't show us, neuron.cpp. Hard to fix what we cant see

    The use of the keyword class in the attach declaration is superfluous.

    memset should be avoided as a way to initialise class types. You might get away with it here but its not recommended at all. Use the constructor initialiser list to set each member to zero or its default value. memset can only be used on POD types.

    Never bring a whole namespace into the global namespace in a header file. In headers explicitly qualify where needed.
    __________________
    Get Microsoft Visual C++ Express here or CodeBlocks here.
    Get STLFilt here to radically improve error messages when using the STL.
    Get these two can't live without C++ libraries, BOOST here and Loki here.
    Check your code with the Comeau Compiler and FlexeLint for standards compliance and some subtle errors.
    Always use [code] code tags [/code] to make code legible and preserve indentation.
    Do not ask for help writing destructive software such as viruses, gamehacks, keyloggers and the suchlike.
    Reply With Quote
      #5    
    Old November 25th, 2009, 03:12 PM
    robione robione is offline
    Junior Member
     
    Join Date: Jan 2009
    Posts: 20
    robione is an unknown quantity at this point (<10)
    Re: Using an undefined class?

    I was missing '#include "Ganglion.h" ' like VladamirF had said. Thanks guys.... I feel more noobish then ever LOL. This has been quite the brain fart on my part.

    Quote:
    Originally Posted by Kheun View Post
    There's nothing wrong in writing neutral network code in OOP....
    True true... I was thinking (and agreeing with this individual that said) avoiding the overhead of objects by using arrays instead would produce faster code. Of course I don't have a super understanding of what happens underneath the hood during compilation. I do know virtual functions add overhead.... as for the rest I'm not sure. Perhaps he was referring to calling one function to act on one array instead of calling essentially the same function x times where x = number of neurons.

    Not a big deal for small networks but I want to try some things based on what my flat panel is displaying at any given time so that's 1280*800*3 nodes in the input layer alone!!! That said I like OOP just because it separates each unit and it's easier for me to see how things are working.

    Quote:
    Originally Posted by Russco View Post
    The use of the keyword class in the attach declaration is superfluous.

    memset should be avoided as a way to initialise class types. You might get away with it here but its not recommended at all. Use the constructor initialiser list to set each member to zero or its default value. memset can only be used on POD types.

    Never bring a whole namespace into the global namespace in a header file. In headers explicitly qualify where needed.
    The 'class' was there in my attempts to get it working. It wasn't there originally.

    I like using memset on structures. Perhaps it's a bad habit developed because I didn't want to type. It works okay as long as the class doesn't have any virtual functions anywhere (methods, part of attributes, parent classes, etc). Perhaps I should convert it to a struct so the possibility of mistakes down the road are smaller. When I code I usually find my structs contain only POD types.

    I'm pretty new to namespaces and their best practices. I just wanted a way to group all the activation functions together.
    Reply With Quote
      #6    
    Old November 25th, 2009, 06:39 PM
    Russco Russco is offline
    Member
     
    Join Date: Nov 2008
    Location: England
    Posts: 478
    Russco has a spectacular aura about (150+) Russco has a spectacular aura about (150+)
    Re: Using an undefined class?

    There are only 2 minor differences between classes and structs. That is class default to private and inheritance defaults to private, and with structs, they default to public and inherit publically by default. Therefore both structs and classes can have constructors and use the initilsation list. Just because in this case you can get away with a memset doesn't necessarily make it a good idea.
    Code:
    CLink() {::memset(this,0,sizeof(*this));}
    
    should be replaced by
    
    CLink() : dWeight(0), pNeuron(NULL)
    {}
    Which really looks the most self-documenting? Which is safe in all cases? This is C++ not C. Use constructors not memset.

    As for namespaces, you shouldn't bring a whole namespace into the global scope in a header file else every file you include that header in will have name pollution and it could possibly completely change the meaning of your program if you unknowingly have a name conflict that causes the wrong function to be called or the wrong variable to be accessed. The idea of namespaces is to avoid name conflicts. You can use 'using namespace std' in the implementation file, but in the header file you should qualify names in the std namespace explicitly by prefixing std:: onto the name in question. This advice stands also for user defined namespaces. Avoid name pollution, its likely to bite you in the *** on larger projects so its a good idea to code the right way from the off, just to get into good habits rather than bad.
    __________________
    Get Microsoft Visual C++ Express here or CodeBlocks here.
    Get STLFilt here to radically improve error messages when using the STL.
    Get these two can't live without C++ libraries, BOOST here and Loki here.
    Check your code with the Comeau Compiler and FlexeLint for standards compliance and some subtle errors.
    Always use [code] code tags [/code] to make code legible and preserve indentation.
    Do not ask for help writing destructive software such as viruses, gamehacks, keyloggers and the suchlike.
    Reply With Quote
      #7    
    Old November 25th, 2009, 10:38 PM
    robione robione is offline
    Junior Member
     
    Join Date: Jan 2009
    Posts: 20
    robione is an unknown quantity at this point (<10)
    Re: Using an undefined class?

    Thanks Russco. I had seen ppl do just that (use std:: in .h files) when looking through posts for quite some time. Now I know why.

    Happy Holidays everyone!!
    Reply With Quote
      #8    
    Old November 26th, 2009, 01:09 AM
    Paul McKenzie Paul McKenzie is offline
    Elite Member
    Power Poster
     
    Join Date: Apr 1999
    Posts: 20,959
    Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+)
    Re: Using an undefined class?

    Quote:
    Originally Posted by robione View Post
    I like using memset on structures. Perhaps it's a bad habit developed because I didn't want to type.
    It is one habit you should drop when you code in C++.
    Quote:
    It works okay as long as the class doesn't have any virtual functions anywhere (methods, part of attributes, parent classes, etc).
    Not true.
    Code:
    #include <string>
    
    struct foo
    {
       std::string x;
    };
    There are no virtual functions in this struct (std::string has no virtual functions either). Using memset on this struct is undefined behaviour, so a simple addition of a member variable has introduced a bug in your program.

    Initialization lists work all the time -- regardless of what the struct or class consists of.

    Also, using memset() in a C++ application, regardless of where you use it, is not recommended. Instead, there is the std::fill() algorithm function. If you have a good implementation, this algorithm function defaults to memset() for simple types, and one-by-one copying for non-POD types -- so you can't go wrong.

    Regards,

    Paul McKenzie
    Reply With Quote
    Reply

    Bookmarks
    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > C++ (Non Visual C++ Issues)


    Thread Tools Search this Thread
    Search this Thread:

    Advanced Search
    Display Modes Rate This Thread
    Rate This Thread:

    Posting Rules
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is On
    Smilies are On
    [IMG] code is On
    HTML code is Off
    Forum Jump


    All times are GMT -5. The time now is 01:04 PM.



    Acceptable Use Policy


    The Network for Technology Professionals

    Search:

    About Internet.com

    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers


    Powered by vBulletin® Version 3.7.3
    Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.