pkirk25 wrote:
Hi,
I want to create a class with its definition in cls.h and
implementation in cls.cpp I get errors about redfinitions and errors
wahtever way I try to initialise the static proivate variable
*log_file.
// cls.h:
class logger
{
public:
void create(char *log_file_name) ;
};
// cls.cpp
class logger
{
public:
void create(char *log_file_name)
{
srtcpy *log_file_name, *log_file);
}
private:
static char *log_file;
};
What is the right way to split this so that compiler knows what I am
trying to do?
The reason you're getting errors about "redefiniti ons" is because you have
indeed defined the class twice. You need to use a different syntax in the cpp
file for implementing the class' member functions.
I'm pretty certain you don't want log_file to be a static variable. (Do you?
What static means in the context of a class is that every class shares that
single variable - so in this case, every logger you create will automatically be
writing to the same file.)
The way you should split your code is like this:
// cls.h
class logger
{
public:
void create(char *log_file_name)
private:
char *log_file;
};
// cls.cpp
void logger::create( char *log_file_name)
{
srtcpy (*log_file_name , *log_file);
}
There are two significant issues with this code. The first is that you've used a
char* to store text: this is very hard, and your code is buggy as a result.
The first bug is that you're passing *log_file_name to the function strtcpy:
this is the value _stored_ at the address log_file_name, and not the _actual
address_, which is what it will certainly be expecting - there's the same thing
with *log_file - to do that you would write srtcpy (log_file_name, log_file).
However, this is still buggy: at the moment, log_file hasn't been initialised
yet, and so doesn't point to anything - or rather, it probably points to some
random piece of memory. This is very bad. I could show you how to sort this out
as well, but in fact there's a much better solution: std::string, in the
standard library, which handles all text processing much better and more easily
than you or I could ever hope to do. Rewritten with std::string your code would
look like this:
// cls.h
#include <string>
using std::string;
class logger
{
public:
void create(string const& log_file_name)
private:
string log_file;
};
// cls.cpp
void logger::create( string const& log_file_name)
{
// guarantees log_file gets its own bit of memory
log_file = log_file_name.s ubstr();
}
A good reference on strings can be found here:
http://www.camtp.uni-mb.si/books/Thi...Chapter01.html
However, there's still more improvements. Have you studied constructors yet? A
constructor is essentially a built-in create function. I won't go into detail
here, but again Thinking in C++ is an excellent reference:
http://www.camtp.uni-mb.si/books/C++/Chapter06.html
Rewritten with a proper constructor, your code becomes this:
// cls.h
#include <string>
using std::string;
class logger
{
public:
logger()
logger(string const& log_file_name)
private:
string log_file;
};
// cls.cpp
logger::logger( )
: log_file ("default.lo g")
{
}
logger::logger( string const& log_file_name)
: log_file (log_file_name. substr());
{
}
Having done that, you can now declare a new logger very straightforward ly:
logger MyLogger("error s.log");
This is quite a lot of information - hope some of it helps...
Tom