Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Include Help Needed

Include Help Needed

Scheduled Pinned Locked Moved C / C++ / MFC
helpquestionc++com
16 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Jeryth

    Steen Krogsgaard wrote: Are you absolutely sure that your problems stems from multiple inclusions of the classA header? I'll say I'm 95% sure that's the cause. All the linking errors mentioned Class A name in the error field. But now I have a new problem. I took Dave Crow's advice and redid my #ifndef statements. Now I'm testing in the class header file if an appropriate preprocessor tag has been defined, if not then it defines it and it continues to have the class declared. If it already has, it skips it. After the initial #ifndef I use separate ones to test for any required includes for that class. For example, Class A looks like this: #ifndef CLASS_B_INC #define CLASS_B_INC #pragma once #ifndef CLASS_A_INC #include "CLASS_A.h" #endif //Rest of Class here #endif I think part of my problem was that I was possibly defining the pre-processor tags multiple times. This way, they only get defined in that class' header file. Note here that Class B won't try to define CLASS_A_INC ( that's left to Class A to do ) it will just include it and when that does Class A will define it on its own. Now something like that written above is in all .h files. The .cpp files only have #ifndef CLASS_A_INC #include "CLASS_A.h" #endif for their own classes, so above would be the Class A .cpp file. Now I'm getting errors that certain elements can't be found such as "cout : undeclared identifier" and "Class E : undeclared identifier" so some of my #include statements aren't being processed and I don't know why. ________________________________________________________________________ The question "Do computers think?" is the same as "Can submarines swim?" Signature Red Studios Jeryth

    S Offline
    S Offline
    Steen Krogsgaard
    wrote on last edited by
    #7

    Jeryth wrote: I'll say I'm 95% sure that's the cause. All the linking errors mentioned Class A name in the error field. Multilple includes will give compiler errors(error C2011: 'CClassA' : 'class' type redefinition), not linking errors! Cheers Steen. "To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

    J 1 Reply Last reply
    0
    • S Steen Krogsgaard

      Jeryth wrote: I'll say I'm 95% sure that's the cause. All the linking errors mentioned Class A name in the error field. Multilple includes will give compiler errors(error C2011: 'CClassA' : 'class' type redefinition), not linking errors! Cheers Steen. "To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

      J Offline
      J Offline
      Jeryth
      wrote on last edited by
      #8

      You're right, I mis-labeled my problem. All classes compiled fine, they just wouldn't link. It was complaining about resolving an exxternal link error or somthing along those lines. ________________________________________________________________________ The question "Do computers think?" is the same as "Can submarines swim?" Signature Red Studios Jeryth

      1 Reply Last reply
      0
      • S Steen Krogsgaard

        I would recommend that you *only* use the #ifndef/#define/#endif in the header file, and that you put only *one* construct for the entire file, as in // in class_b.h: ifndef CLASS_B_INC #define CLASS_B_INC #pragma once #include "CLASS_A.h" //Rest of Class here #endif // in class_a.h: ifndef CLASS_A_INC #define CLASS_A_INC #pragma once class A : ..... { ... } #endif You don't need to put #ifndef/#endif around the #include statement in class_b.h. If class_a.h has already been parsed CLASS_A_INC will be defined and it won't be parsed again (it will be an empty file as the preprocessor will remove everything between #ifndef/#endif, and here that means everything in class_a.h), and you will effectively include an empty file. This, IMHO, is much cleaner than putting #ifndef/#endif around every single #include statement in your project. Are you still sure that #pragma once does not solve your problem by itself, i.e. without all the #ifndef/#endif stuff? It does for me. I think MS put #if !defined/#endif for backwards-compatibility reasons (i.e. _MSC_VER <= 1000) Cheers Steen. "To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

        J Offline
        J Offline
        Jeryth
        wrote on last edited by
        #9

        Okay so I changed those and it cleared up some of the mess. But the old errors came back. In the errors below, CABLE is what I've been referring to as Class A and TABLE is Class F, the bottom tier one. error LNK2019: unresolved external symbol "public: __thiscall CABLE::~CABLE(void)" (??1CABLE@@QAE@XZ) referenced in function "public: __thiscall TABLE::TABLE(int)" (??0TABLE@@QAE@H@Z) error LNK2019: unresolved external symbol "public: __thiscall CABLE::~CABLE(void)" (??1CABLE@@QAE@XZ) referenced in function __unwindfunclet$??0CARD@@QAE@XZ$0 Looks like it doens't know where to go for CABLE function calls. Any ideas? ________________________________________________________________________ The question "Do computers think?" is the same as "Can submarines swim?" Signature Red Studios Jeryth

        S 1 Reply Last reply
        0
        • J Jeryth

          Okay so I changed those and it cleared up some of the mess. But the old errors came back. In the errors below, CABLE is what I've been referring to as Class A and TABLE is Class F, the bottom tier one. error LNK2019: unresolved external symbol "public: __thiscall CABLE::~CABLE(void)" (??1CABLE@@QAE@XZ) referenced in function "public: __thiscall TABLE::TABLE(int)" (??0TABLE@@QAE@H@Z) error LNK2019: unresolved external symbol "public: __thiscall CABLE::~CABLE(void)" (??1CABLE@@QAE@XZ) referenced in function __unwindfunclet$??0CARD@@QAE@XZ$0 Looks like it doens't know where to go for CABLE function calls. Any ideas? ________________________________________________________________________ The question "Do computers think?" is the same as "Can submarines swim?" Signature Red Studios Jeryth

          S Offline
          S Offline
          Steen Krogsgaard
          wrote on last edited by
          #10

          Jeryth wrote: Looks like it doens't know where to go for CABLE function calls No, it looks like it doesn't know where to go for CABLE::~CABLE(void), i.e. the destructor of your CABLE class. Did you perhaps by any chance forgot to define it?:rolleyes: It looks as it's declared in the class allright but not defined in a cpp file. I wonder why you're calling CABLE::~CABLE in TABLE's constructor, looks to me as inefficient member variabel initialization ;) Cheers Steen. "To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

          J 1 Reply Last reply
          0
          • S Steen Krogsgaard

            Jeryth wrote: Looks like it doens't know where to go for CABLE function calls No, it looks like it doesn't know where to go for CABLE::~CABLE(void), i.e. the destructor of your CABLE class. Did you perhaps by any chance forgot to define it?:rolleyes: It looks as it's declared in the class allright but not defined in a cpp file. I wonder why you're calling CABLE::~CABLE in TABLE's constructor, looks to me as inefficient member variabel initialization ;) Cheers Steen. "To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

            J Offline
            J Offline
            Jeryth
            wrote on last edited by
            #11

            Yeah, saw the destructor reference and that was the first thing I checked before I posted. If only it would have been so easy. I'm not explicitly calling for any CABLEs to be made in the TABLE constructor. I'm creating some other objects that have CABLEs in them, but I'm pretty sure none of them are getting destroyed. I've got one implicit cast where I grab a line from cout and pass that into a function that's looking for a CABLE, so the VS is just doing that on its own. Don't know where the problem might be coming from. ________________________________________________________________________ The question "Do computers think?" is the same as "Can submarines swim?" Signature Red Studios Jeryth

            S 1 Reply Last reply
            0
            • J Jeryth

              Yeah, saw the destructor reference and that was the first thing I checked before I posted. If only it would have been so easy. I'm not explicitly calling for any CABLEs to be made in the TABLE constructor. I'm creating some other objects that have CABLEs in them, but I'm pretty sure none of them are getting destroyed. I've got one implicit cast where I grab a line from cout and pass that into a function that's looking for a CABLE, so the VS is just doing that on its own. Don't know where the problem might be coming from. ________________________________________________________________________ The question "Do computers think?" is the same as "Can submarines swim?" Signature Red Studios Jeryth

              S Offline
              S Offline
              Steen Krogsgaard 2
              wrote on last edited by
              #12

              Of course I didn't mean to imply that you would make such an elementary error :-D, but there's no question (at least in my mind :)) that the linker can't find the implementation of CABLE::~CABLE, so something's gotta be wrong. You could try to put {} after the declaration in header file to make ~CABLE inline, that way you're sure it's defined: class CABLE { public: virtual ~CABLE() {}; } If that gets rid of the linker error then recheck the definition of ~CABLE in your code. Regarding calling of the constructor, it's called when temporary CABLE objects are constructed and destructed, for example during an assignment. Furthermore, the second linker error indicates that the destructor is called from a structured exception handler (the "_unwindfunclet" part sounds like stack unwinding to me) Perhaps you could post some code to show the declaration and implemenations, or is it too large chunks? cheers Steen (from my home computer)

              J 1 Reply Last reply
              0
              • S Steen Krogsgaard 2

                Of course I didn't mean to imply that you would make such an elementary error :-D, but there's no question (at least in my mind :)) that the linker can't find the implementation of CABLE::~CABLE, so something's gotta be wrong. You could try to put {} after the declaration in header file to make ~CABLE inline, that way you're sure it's defined: class CABLE { public: virtual ~CABLE() {}; } If that gets rid of the linker error then recheck the definition of ~CABLE in your code. Regarding calling of the constructor, it's called when temporary CABLE objects are constructed and destructed, for example during an assignment. Furthermore, the second linker error indicates that the destructor is called from a structured exception handler (the "_unwindfunclet" part sounds like stack unwinding to me) Perhaps you could post some code to show the declaration and implemenations, or is it too large chunks? cheers Steen (from my home computer)

                J Offline
                J Offline
                Jeryth
                wrote on last edited by
                #13

                No, no, I've been known to make basic mistakes. Nearly tore all my hair out after typing 50 pages of code and couldn't get it to compile. Then found a missing semicolon about 20 lines up from where the compiler had flagged the error. No, found out the problem. I had CABLE files in a different directory ( I wanted to keep them in a generic use folder ) and had added that directory to the project include folders, but had not added the files themselves to the project. Now compiling and linking is fine, but I've got yet ANOTHER problem. I run the program in the debugger and after I get through a few menus, I get this: DAMAGE: before Normal block ( #92 ) at ( 0x00323798 ) In stepping back through the debugger, it hilights the CABLE destructor. In particular, the line delete [] cable; The cable var is a char * array so I don't know why it wouldn't be able to delete it. Any ideas here? ________________________________________________________________________ The question "Do computers think?" is the same as "Can submarines swim?" Signature Red Studios Jeryth

                S 1 Reply Last reply
                0
                • J Jeryth

                  No, no, I've been known to make basic mistakes. Nearly tore all my hair out after typing 50 pages of code and couldn't get it to compile. Then found a missing semicolon about 20 lines up from where the compiler had flagged the error. No, found out the problem. I had CABLE files in a different directory ( I wanted to keep them in a generic use folder ) and had added that directory to the project include folders, but had not added the files themselves to the project. Now compiling and linking is fine, but I've got yet ANOTHER problem. I run the program in the debugger and after I get through a few menus, I get this: DAMAGE: before Normal block ( #92 ) at ( 0x00323798 ) In stepping back through the debugger, it hilights the CABLE destructor. In particular, the line delete [] cable; The cable var is a char * array so I don't know why it wouldn't be able to delete it. Any ideas here? ________________________________________________________________________ The question "Do computers think?" is the same as "Can submarines swim?" Signature Red Studios Jeryth

                  S Offline
                  S Offline
                  Steen Krogsgaard 2
                  wrote on last edited by
                  #14

                  I think you made a memory overwrite somewhere in your code. MFC new puts guard bytes around your allocated block and checks if something has screwed up your block everytime you call new or delete - that's why you get the message in the destructor, as that's probably the first time after the error occurred that new or delete gets called. Alas, it has nothing to do with the destructor or the delete[] call as such. See this[^] MSDN article for more info. Recheck your code for places where you use strcpy or similar function without checking the length of the arguments, especially your cable variable. Use strncpy instead. Cheers Steen

                  J 1 Reply Last reply
                  0
                  • S Steen Krogsgaard 2

                    I think you made a memory overwrite somewhere in your code. MFC new puts guard bytes around your allocated block and checks if something has screwed up your block everytime you call new or delete - that's why you get the message in the destructor, as that's probably the first time after the error occurred that new or delete gets called. Alas, it has nothing to do with the destructor or the delete[] call as such. See this[^] MSDN article for more info. Recheck your code for places where you use strcpy or similar function without checking the length of the arguments, especially your cable variable. Use strncpy instead. Cheers Steen

                    J Offline
                    J Offline
                    Jeryth
                    wrote on last edited by
                    #15

                    Hmm, I didn't make this an MFC project per se, just started with an empty solution but I guess some MFC is still being put it automatically. That link was rather helpful, shows the same error message I'm getting so that should be the right track. I'm not using strcpy or strncpy anywhere. I use my own loops to copy element by element in CABLE. In fact the only string function I think I'm using is strlen. Here's the CABLE class in it's entirty. It's pretty simplistic, I'm pretty much just doing it for practice with plans to add on to it as I learn more.

                    #include CABLE::CABLE()
                    {
                    cable = new char[1];
                    cable[0] = '\0';
                    length = 0;
                    }

                    //Private constructor, used only to create a temp CABLE of set size that is NULL filled.
                    CABLE::CABLE( int newLength )
                    {
                    cable = new char[newLength+1];
                    length = newLength;
                    for( int i = 0; i <= length; ++i )
                    {
                    cable[i] = '\0';
                    }
                    }

                    CABLE::CABLE( const char * const newCable )
                    {
                    length = strlen( newCable );
                    cable = new char [length+1];
                    for( int i = 0; i <= length; ++i )
                    {
                    cable[i] = newCable[i];
                    }
                    cable[length] = '\0';
                    }

                    CABLE::CABLE( const CABLE & rhs )
                    {
                    length = rhs.GetLength();
                    cable = new char[length+1];
                    for( int i = 0; i <= length; ++i )
                    {
                    cable[i] = rhs[i];
                    }
                    cable[length] = '\0';
                    }

                    CABLE::~CABLE()
                    {
                    delete cable;
                    cable = NULL;
                    length = 0;
                    }

                    CABLE & CABLE::operator=( const CABLE & rhs )
                    {
                    if ( this != &rhs )
                    {
                    delete [] cable;
                    length = rhs.GetLength();
                    cable = new char[length+1];
                    for( int i = 0; i <= length; ++i )
                    {
                    cable[i] = rhs[i];
                    }
                    cable[length] = '\0';
                    }

                    return \*this;
                    

                    }

                    char & CABLE::operator[]( int offset )
                    {
                    if ( offset > length )
                    {
                    return cable[length-1];
                    }
                    else
                    {
                    return cable[offset];
                    }
                    }

                    char CABLE::operator[]( int offset ) const
                    {
                    if ( offset > length )
                    {
                    return cable[length-1];
                    }
                    else
                    {
                    return cable[offset];
                    }
                    }

                    CABLE CABLE::operator+( const CABLE & rhs )
                    {
                    int totalLength = length + rhs.GetLength();
                    CABLE temp( totalLength );
                    for( int i = 0; i < length; ++i )
                    {
                    temp[i] = cable[i];
                    }
                    for( int j = 0; j < rhs.GetLength(); ++j, ++i )
                    {
                    temp[i] = rhs[j];
                    }
                    temp[totalLength] = '\0';

                    return temp;
                    

                    }

                    void CABLE::operator+=( const CABLE & rhs )
                    {
                    int totalLength = length + rhs.GetLength();
                    CABLE temp( totalLength );
                    for( int i = 0; i < length; ++i )
                    {
                    temp[i] = cable[i];
                    }
                    for( int j = 0;

                    S 1 Reply Last reply
                    0
                    • J Jeryth

                      Hmm, I didn't make this an MFC project per se, just started with an empty solution but I guess some MFC is still being put it automatically. That link was rather helpful, shows the same error message I'm getting so that should be the right track. I'm not using strcpy or strncpy anywhere. I use my own loops to copy element by element in CABLE. In fact the only string function I think I'm using is strlen. Here's the CABLE class in it's entirty. It's pretty simplistic, I'm pretty much just doing it for practice with plans to add on to it as I learn more.

                      #include CABLE::CABLE()
                      {
                      cable = new char[1];
                      cable[0] = '\0';
                      length = 0;
                      }

                      //Private constructor, used only to create a temp CABLE of set size that is NULL filled.
                      CABLE::CABLE( int newLength )
                      {
                      cable = new char[newLength+1];
                      length = newLength;
                      for( int i = 0; i <= length; ++i )
                      {
                      cable[i] = '\0';
                      }
                      }

                      CABLE::CABLE( const char * const newCable )
                      {
                      length = strlen( newCable );
                      cable = new char [length+1];
                      for( int i = 0; i <= length; ++i )
                      {
                      cable[i] = newCable[i];
                      }
                      cable[length] = '\0';
                      }

                      CABLE::CABLE( const CABLE & rhs )
                      {
                      length = rhs.GetLength();
                      cable = new char[length+1];
                      for( int i = 0; i <= length; ++i )
                      {
                      cable[i] = rhs[i];
                      }
                      cable[length] = '\0';
                      }

                      CABLE::~CABLE()
                      {
                      delete cable;
                      cable = NULL;
                      length = 0;
                      }

                      CABLE & CABLE::operator=( const CABLE & rhs )
                      {
                      if ( this != &rhs )
                      {
                      delete [] cable;
                      length = rhs.GetLength();
                      cable = new char[length+1];
                      for( int i = 0; i <= length; ++i )
                      {
                      cable[i] = rhs[i];
                      }
                      cable[length] = '\0';
                      }

                      return \*this;
                      

                      }

                      char & CABLE::operator[]( int offset )
                      {
                      if ( offset > length )
                      {
                      return cable[length-1];
                      }
                      else
                      {
                      return cable[offset];
                      }
                      }

                      char CABLE::operator[]( int offset ) const
                      {
                      if ( offset > length )
                      {
                      return cable[length-1];
                      }
                      else
                      {
                      return cable[offset];
                      }
                      }

                      CABLE CABLE::operator+( const CABLE & rhs )
                      {
                      int totalLength = length + rhs.GetLength();
                      CABLE temp( totalLength );
                      for( int i = 0; i < length; ++i )
                      {
                      temp[i] = cable[i];
                      }
                      for( int j = 0; j < rhs.GetLength(); ++j, ++i )
                      {
                      temp[i] = rhs[j];
                      }
                      temp[totalLength] = '\0';

                      return temp;
                      

                      }

                      void CABLE::operator+=( const CABLE & rhs )
                      {
                      int totalLength = length + rhs.GetLength();
                      CABLE temp( totalLength );
                      for( int i = 0; i < length; ++i )
                      {
                      temp[i] = cable[i];
                      }
                      for( int j = 0;

                      S Offline
                      S Offline
                      Steen Krogsgaard 2
                      wrote on last edited by
                      #16

                      If it's not an MFC App Wizard generated project you shouldn't have any MFC. The only thing I can see in your code is that you use delete cable instead of delete[] cable in the destructor, but from your previous post I guess that's a typo (you said earlier that the debugger highlighted delete[] cable in the destructor). How is CABLE used in your code? Which methods are called? That may give some clues. Cheers Steen

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups