🔒 Locked
How come...
Advertisement
Original Post
How come when I declare a class with the .h and .cpp, sometimes I have to #include the .cpp at the bottom of my .h file, and sometimes I don''t.
My problem, to make it more clear, is when I declare a class with a header and implementation file, when I go to compile and run my program, sometimes I get a bunch of unresolved external errors when it tries to link my .h and .cpp together.
To fix the problem, I simply #include the .cpp after the class declaration in the .h file, which I shouldn''t have to, but it fixes the problem. This will clear the problem up until after working on my program some more, and trying to link all the files again, I''ll get the same error as before, and to fix it up this time, I simply remove the #include .cpp from the .h file, then everything works fine again. And this basically just goes back and forth with my removing the .cpp then next time including the .cpp.
Does anybody know why this is. I''m using Visual Studio 6, C++, and I''m not using templates or anything like that. I do have the #include .h in the .cpp, and use ifndef blah define blah in both my .h and .cpp. Also, I do not have this problem with just this class, it has happened with others, but does not happen with all of them.
Anybody have any ideas? Thanks in advance
- Dan
He who laughs, lasts
Also, normally I do "never" include the .cpp files, it''s just that it was the only way I could get my program to work. Oh, except for when I use templates, then you have to either put both the header and implementation in one file, or include the .cpp in the .h for it to work. At least, as far as I know you have to, that''s what my prof told me and it was the only way we could get them to work.
- Dan
He who laughs, lasts
- Dan
He who laughs, lasts
I don't use ifndef anymore.
I use:
#pragma once
Write the above line in at least in your header file.
It will force all the files that contain to be included
only once, preventing redefenitions.
You "main" source file should call all the headers of
the classes youre using.
People will bitch about the usage of "#pragma once"
because it only works in visual c++, it isn't supported by
borland, blah blah blah. Just use, if its simpler, use it.
Try it out on all your headers, don't forget to remove
your ifndefs, or it might blow up, and if it still gives an
error come back here and tell us what it is.
[edited by - pentium3id on March 2, 2003 12:37:10 AM]
I use:
#pragma once
Write the above line in at least in your header file.
It will force all the files that contain to be included
only once, preventing redefenitions.
You "main" source file should call all the headers of
the classes youre using.
People will bitch about the usage of "#pragma once"
because it only works in visual c++, it isn't supported by
borland, blah blah blah. Just use, if its simpler, use it.
Try it out on all your headers, don't forget to remove
your ifndefs, or it might blow up, and if it still gives an
error come back here and tell us what it is.
[Hugo Ferreira][Positronic Dreams]
Need [3D Artist] & [Sound Designer]
for small project. Contact me plz...
[edited by - pentium3id on March 2, 2003 12:37:10 AM]
You should only use inclusion guards ( the #ifndef ... ) in your header files, not in your source-files. This would probably explain why you get unresolved external errors.
pentium3id:
The problem with using #pragma once isn''t that it''s not supported by Borland and others, but that it isn''t Standard, and that a perfectly good Standard alternative exists. You should always do things the standard way if it offers the same functionality.
-Neophyte
pentium3id:
The problem with using #pragma once isn''t that it''s not supported by Borland and others, but that it isn''t Standard, and that a perfectly good Standard alternative exists. You should always do things the standard way if it offers the same functionality.
-Neophyte
make sure the cpp file has been added to the project or makefile or whatever you''re using with your compiler.
quote:
Original post by pentium3id
People will bitch about the usage of "#pragma once"
because it only works in visual c++, it isn''t supported by
borland, blah blah blah. Just use, if its simpler, use it.
Actually, if you pay attention to the exact definition of #pragma once, you''ll see that it says the file will not be opened several times. Which doesn''t mean that it won''t be inserted several times.
It is a speed optimization which is orthogonal to the presence of #include guards. Behaviour may change at any time (and has in the past).
If you look at MSVC wizard-generated sources, you''ll notice they usually have both a #pragma once and #include guards (on some random GUID string)
This alone should raise a flag.
There was a discussion on the topic in the Boost mailing list, the most directly relevant post is here.
[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]
I stand corrected. Thanx for the heads up.
[Hugo Ferreira][Positronic Dreams]
Need [3D Artist] & [Sound Designer]
for small project. Contact me plz...
This is the exact error I get:
Linking...
Connex.obj : error LNK2005: "public: __thiscall CBlock::CBlock(int,int,int,int,int,int,int,int)" (??0CBlock@@QAE@HHHHHHHH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: __thiscall CBlock::~CBlock(void)" (??1CBlock@@QAE@XZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: void __thiscall CBlock::ChangeBlockType(int)" (?ChangeBlockType@CBlock@@QAEXH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::RotateBlockClockwise(void)" (?RotateBlockClockwise@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::RotateBlockCounterClockwise(void)" (?RotateBlockCounterClockwise@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::MoveBlockLeft(void)" (?MoveBlockLeft@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::MoveBlockRight(void)" (?MoveBlockRight@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::MoveBlockDown(void)" (?MoveBlockDown@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::MoveBlockUp(void)" (?MoveBlockUp@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::MoveEntireBlockToCell(int,int)" (?MoveEntireBlockToCell@CBlock@@QAE_NHH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: int __thiscall CBlock::ReturnBlockCellRow(void)const " (?ReturnBlockCellRow@CBlock@@QBEHXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: int __thiscall CBlock::ReturnBlockCellColumn(void)const " (?ReturnBlockCellColumn@CBlock@@QBEHXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: int __thiscall CBlock::ReturnBlockStartingCellRow(void)const " (?ReturnBlockStartingCellRow@CBlock@@QBEHXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: int __thiscall CBlock::ReturnBlockStartingCellColumn(void)const " (?ReturnBlockStartingCellColumn@CBlock@@QBEHXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::IsEntireBlockMoveValid(struct sBlock &)const " (?IsEntireBlockMoveValid@CBlock@@QBE_NAAUsBlock@@@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: void __thiscall CBlock:
laceEntireBlockOnBoard(int)" (?PlaceEntireBlockOnBoard@CBlock@@QAEXH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: void __thiscall CBlock::EraseEntireBlockFromBoard(void)" (?EraseEntireBlockFromBoard@CBlock@@QAEXXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::SetBlockCellRow(int)" (?SetBlockCellRow@CBlock@@QAE_NH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::SetBlockCellColumn(int)" (?SetBlockCellColumn@CBlock@@QAE_NH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::SetBlockCellStartRow(int)" (?SetBlockCellStartRow@CBlock@@QAE_NH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::SetBlockCellStartColumn(int)" (?SetBlockCellStartColumn@CBlock@@QAE_NH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: void __thiscall CBlock::DrawAllBlocks(void)" (?DrawAllBlocks@CBlock@@QAEXXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "private: void __thiscall CBlock::LoadBlocksIntoBlockData(void)" (?LoadBlocksIntoBlockData@CBlock@@AAEXXZ) already defined in CBlock.obj
Debug/Connex.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.
- Dan
He who laughs, lasts
Linking...
Connex.obj : error LNK2005: "public: __thiscall CBlock::CBlock(int,int,int,int,int,int,int,int)" (??0CBlock@@QAE@HHHHHHHH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: __thiscall CBlock::~CBlock(void)" (??1CBlock@@QAE@XZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: void __thiscall CBlock::ChangeBlockType(int)" (?ChangeBlockType@CBlock@@QAEXH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::RotateBlockClockwise(void)" (?RotateBlockClockwise@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::RotateBlockCounterClockwise(void)" (?RotateBlockCounterClockwise@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::MoveBlockLeft(void)" (?MoveBlockLeft@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::MoveBlockRight(void)" (?MoveBlockRight@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::MoveBlockDown(void)" (?MoveBlockDown@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::MoveBlockUp(void)" (?MoveBlockUp@CBlock@@QAE_NXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::MoveEntireBlockToCell(int,int)" (?MoveEntireBlockToCell@CBlock@@QAE_NHH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: int __thiscall CBlock::ReturnBlockCellRow(void)const " (?ReturnBlockCellRow@CBlock@@QBEHXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: int __thiscall CBlock::ReturnBlockCellColumn(void)const " (?ReturnBlockCellColumn@CBlock@@QBEHXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: int __thiscall CBlock::ReturnBlockStartingCellRow(void)const " (?ReturnBlockStartingCellRow@CBlock@@QBEHXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: int __thiscall CBlock::ReturnBlockStartingCellColumn(void)const " (?ReturnBlockStartingCellColumn@CBlock@@QBEHXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::IsEntireBlockMoveValid(struct sBlock &)const " (?IsEntireBlockMoveValid@CBlock@@QBE_NAAUsBlock@@@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: void __thiscall CBlock:
Connex.obj : error LNK2005: "public: void __thiscall CBlock::EraseEntireBlockFromBoard(void)" (?EraseEntireBlockFromBoard@CBlock@@QAEXXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::SetBlockCellRow(int)" (?SetBlockCellRow@CBlock@@QAE_NH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::SetBlockCellColumn(int)" (?SetBlockCellColumn@CBlock@@QAE_NH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::SetBlockCellStartRow(int)" (?SetBlockCellStartRow@CBlock@@QAE_NH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: bool __thiscall CBlock::SetBlockCellStartColumn(int)" (?SetBlockCellStartColumn@CBlock@@QAE_NH@Z) already defined in CBlock.obj
Connex.obj : error LNK2005: "public: void __thiscall CBlock::DrawAllBlocks(void)" (?DrawAllBlocks@CBlock@@QAEXXZ) already defined in CBlock.obj
Connex.obj : error LNK2005: "private: void __thiscall CBlock::LoadBlocksIntoBlockData(void)" (?LoadBlocksIntoBlockData@CBlock@@AAEXXZ) already defined in CBlock.obj
Debug/Connex.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.
- Dan
He who laughs, lasts
Don''t put the CBlock.cpp file in the CBlock.h file
Insert the CBlock.cpp file put it into your project. The file will compile into an object file which will then be linked with whatever other .cpp files are using the CBlock.h file. They will find the functions defined just once in the CBlock.obj file.
Okay?
Insert the CBlock.cpp file put it into your project. The file will compile into an object file which will then be linked with whatever other .cpp files are using the CBlock.h file. They will find the functions defined just once in the CBlock.obj file.
Okay?
Thnx for all the replies everyone. The problem was just that I was using the ifndef and define''s in my .cpp as well as my .h''s. Once I took them out of my .cpp file, everything worked fine without the include .cpp in the .h. So winner was Neophyte. Thnx for the solution, and thanks for all the other suggestions from everyone else.
- Dan
He who laughs, lasts
- Dan
He who laughs, lasts
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement