|
#include "Animal.cpp"
you will almost never ever #include a .CPP file.
try #include "Animal.h"
|
|
|
|
|
I'm confused about where I should put the declarations for my classes and where to put the definitions. When reading my book I got the impression that a header file would contain only the class declarations, and that it would come with an associated .cpp file which contained the definitions. In the book they include the .cpp definition file from their main file, which then includes the .h declaration file at the top.
If I move all of the definitions from the .cpp file into the .h file with the declarations, and include the header file all at once, it works fine. But my book says that the definitions and declarations should be in different files...
Should they be in the same file, or different files, and if so, how must I include them?
|
|
|
|
|
they should be in different files (except in special cases like inline functions or templates - which you don't need to worry about here).
and you should only #include the .H files. somtimes .H files will #include other .H files.
senthryl wrote: In the book they include the .cpp definition file from their main file, which then includes the .h declaration file at the top.
that's very very unusual - there's almost no good reason to do that in 99.99% of the situations you're likely encounter. they might be trying to get out of telling the compiler to explicity compile the .CPP (by #including it, the compiler will compile it as part of the main file), but with Visual Studio, it's trivial to add the .CPP to the project so the compler can compile it separately.
-- modified at 11:16 Sunday 13th August, 2006
|
|
|
|
|
Perfect! I just stored the declarations in another header file and included that from the definition header file.
So I have main.cpp which includes Animal.h (containing the definitions) which includes Animal_Dec.h (containing the declarations).
It's odd, the book says:
"The definition must be in a file that the compiler can find. Most C++ compilers want that file to end with .c or .cpp. This book uses .cpp, but check your compiler to see what it prefers."
Apparently I didn't check my compiler to see what it prefers Although I would have thought that they would give proper instructions for VC6 anyway, since that is what the book is mainly written for...
Thanks for your help!
|
|
|
|
|
declarations go in .H files.
definitions go in .CPP. you will probably never need to #include a definition.
you should add both files types to the Visual Studio project.
|
|
|
|
|
I now have main.cpp, Animal.cpp, and Animal.h.
Animal.h has the declarations.
Animal.cpp has the definitions, and #includes Animal.h.
main.cpp has the driver program, and also #includes Animal.h.
Is that correct?
|
|
|
|
|
senthryl wrote: Is that correct?
yep. exactly.
|
|
|
|
|
The C++ model is that any function can be implemented in any translation unit, so long as there are not multiple definitions: that's what the LNK2005 error is telling you, that the same functions were defined more than once.
A 'translation unit' is the standardese for the result of preprocessing a given input. It's given this odd name because the input doesn't necessarily have to be a file - some C++ compilers will accept input from standard input or another redirected stream, although of course in practice this isn't very useful.
It's worth understanding that the #include statement simply pastes - includes - the contents of the referenced file into the current file at that point. This is the source of the multiple inclusions problem - that you can get 'multiply defined symbol' errors if you include a file more than once in any given translation unit. The traditional workaround is to wrap the whole 'header' file like this:
#ifndef __UNIQUE_SYMBOL__
#define __UNIQUE_SYMBOL__
#endif // __UNIQUE_SYMBOL__ You change __UNIQUE_SYMBOL__ for every new header file, so that each file has a unique definition. This so-called '#ifdef guard' effectively removes the contents of the file from the second definition. Microsoft's compilers since Visual C++ 4.0 support #pragma once which simply tells the compiler not to include this file again if it is encountered again, which is a little quicker than opening the file and noticing that the macro at the top is already defined. This feature is now supported by a number of other compilers.
In order to use a class, structure, or enumeration in a given translation unit, you must declare it. Traditionally this is done by including a so-called header file (traditionally given the .h extension although you might see .hpp or .hxx for C++ headers, but it can have any extension you like, or none in the case of the C++ standard library headers). You can simply redeclare the class in the second file but you can then have problems if the declarations get out of sync, which is why the #include mechanism exists.
It's best to think of each translation unit - each .cpp file - as being compiled completely independently from all the others, although the Microsoft compiler actually can work more efficiently with a batch of source files all specified on the same command line, and particularly with the Pre-Compiled Headers feature.
If you only refer to the class with a pointer (or reference), and never dereference the pointer (or reference), you can simply forward declare it, for example:
class MyClass; You have to use the right keyword, so if it's declared as a struct you must forward-declare it as a struct.
If you define a new class using Visual Studio's wizards, it creates a header and a single .cpp file matching the class's name, but this is simply convention - you can define as many classes in a single header as you like, and you can implement multiple classes in a single file or a single class in multiple files, as you prefer. You might split a class into multiple files if the implementation is very large, to speed up compiles - the compiler will only recompile those files that have actually changed. You might be advised to reduce the number of methods in the class if that occurs, however. It is generally considered best practice to declare only one class in a header and implement it in a single source file, unless there are good reasons not to.
|
|
|
|
|
This is what I have:
class CGraphicsSystem
{
public:
class CImage
{
public:
... // public functions
DrawRectGradient(RECT&, CGradient&);
};
class CGradient
{
... // public functions and protected member variables
friend CImage::DrawRectGradient(RECT&, CGradient&);
};
};
I'm getting compiler error:
error C2245: nonexistent function 'CGraphicsSystem::CImage::DrawRectGradient' specified as friend
Why??
Joel Becker
|
|
|
|
|
If you're just using CGraphicsSystem as a container for other classes, you may be better off defining it as a namespace rather than as a class .
|
|
|
|
|
Thanks for replying.
I actually have quite a bit of data and functions in the CGraphicsSystem class; I just showed the minimum code to highlight my problem. Any suggestions?
Thanks.
|
|
|
|
|
I guess CGradient is previously declared outside CGraphicsSystem (to make CImage compile).
Did you purposely cut out the return value types, or are the functions declared without them?
|
|
|
|
|
Hey!
Ok, I do have the return types in my actual code (so I redid it below).
But here's the thing: CGradient is defined AFTER CImage (both within CGraphicsSystem). Could this be why I'm getting the 2 errors:
error C2245: nonexistent function 'CGraphicsSystem::CImage::DrawRectGradient' specified as friend
error C2511: 'DrawRectGradient' : overloaded member function 'void (struct QGame::QGRECT &,class QGame::CGraphicsSystem::CGradien
t &)' not found in 'QGame::CGraphicsSystem::CImage'
c:\documents and settings\joel&sophia\my documents\computers\programming\vc++\libs\qgamelib\include\qggraph.hpp(199) : see declaration of 'CImage'
? The thing is, if I define it BEFORE, then I get an error for using CImage before it was defined (for the "friend CImage::..." line). (Or maybe you were talking about the actual class declarations before the definitions. Anyway, please help! Thanks)
Here's again what I have
class CGraphicsSystem;
class CImage;
class CGradient;
class CGraphicsSystem
{
public:
class CImage
{
public:
... // public functions
void DrawRectGradient(RECT&, CGradient&);
};
class CGradient
{
... // public functions and protected member variables
friend void CImage::DrawRectGradient(RECT&, CGradient&);
};
};
Joel Becker
|
|
|
|
|
You wrote: Or maybe you were talking about the actual class declarations before the definitions
Yes, indeed. If you like to keep this design, move the class CGradient; declaration to the public section of CGraphicsSystem .
However, I'd suggest NOT to embed image/gradient classes in CGraphicsSystem , to avoid complex constructions later. You'd better create a namespace, so you can write using namespace GraphicsSystem; in your .cpp files and make everything more readable.
You're welcome.
-- modified at 17:47 Sunday 13th August, 2006
|
|
|
|
|
Hey, it worked to move the declarations into CGraphicsSystem! (guess you're not surprised.)
So far the architecure has worked fine. I'm just adding more features. But I'm curious, what are the "complex construction" situations you were talking about? Doesn't CGraphicsSystem simple contain CImage's and CGradients? (since it doesn't have to do with, for example, the CSoundSystem) Maybe my architecture has OO design problems?
Thanks again. Later.
Joel
|
|
|
|
|
<big>Nevermind, I got it...</big>
-- modified at 8:00 Sunday 13th August, 2006
|
|
|
|
|
Great!
Would be nice if you can share it with us.
Ovidiu Cucu
Microsoft MVP - Visual C++
|
|
|
|
|
Hi,
I tried pEdit->SetWindowText("/n"); but a junk character is displayed instead of going to new line .
Plz help.
|
|
|
|
|
Put "\r\n" instead of "\n"
Also be sure the edit control is multiline (has ES_MULTILINE style).
Ovidiu Cucu
Microsoft MVP - Visual C++
|
|
|
|
|
At some time in the past, Life was simple, we had telex machines, printing on rolls of paper! In those days, when at the end of a line, the next step was sinple, you send a signal to make the paper advance one line, a \NL symbol, and you followed it by a Carriage Return Symbol, a \CR Symbol! Then the CRT Screen was invented, and everyone took a step back. What shall we bo when we are at the end of a line: Send a NL, Send a CR, or send a totally new magic incantation. There was never any agreement on this issue, and it still seeps through into the WIN32 in unexpected ways. for instance, in opening files. By reason of history, if you open or save a Textfile, e.g. by using FILE f = fopen(!MyFile.txt","a+"), any New Line Char (\n) will actuallly be translated on the fly to a '\r\n' pair. When reading back, every '\r\n' pair will be converted on the fly to be read into memory as a '\n'. You may avoid this translation on the fly by opening your files as "a+b" (b for Binary). The purpose of the above is to explain that Microsoft maintains two text formats, The one used in a Program, and the One stored on File! This is all without good reason, but that's the way it is, anyways. The problem is, that Microsoft is not consistent in how the rule is applied! For some reason, best known to both God and Bill Gates, certain controls expect the '\r\n' pair, or in others the '\n\r' pair to work propperly. Try to replace each '\n' with an '\r\n' or an '\xa','\xd' pair. You may have to copy your strings into a buffer to do so, I've been doing so for a long time, Unfortunately, that's the only way it seems to work! By the way, Your resource NEEDS to be flagged as MULTILINE for any of the above to work!
LateNightsInNewry
|
|
|
|
|
Hi..
I'm using Visual C++ 6.0.
I have Downloaded and installed the Platform SDK Redistributable: GDI+ (File Name: gdiplus_dnld.exe Version: 3102.1360 ) to the computer.But I cannot compile GDI+ included project .It says that no such directory or file.The error code is given below.
Compiling resources...
Compiling...
StdAfx.cpp
d:\_thisara\gdi_c++\gdi++\stdafx.h(22) : fatal error C1083: Cannot open include file: 'gdiplus.h': No such file or directory
Error executing cl.exe.
Please tell me what else I have to do inorder to proceed with GDI+ with VC++ 6.0
Thanks
ENTC
UoM
|
|
|
|
|
The redistributable is the package a user installs to use GDI+. You need the GDI+ SDK.
|
|
|
|
|
i want a com (vc++) project. please help me.
|
|
|
|
|
How much you pay for that?
Ovidiu Cucu
Microsoft MVP - Visual C++
|
|
|
|
|
|