1

I have a single global class instance:

myclass.h

class Cmyclass {
public:
  void log(const char* msg);
  void set_file(std::string file);
private:
  std::string file;
};

myclass.cpp

void Cmyclass::log(const char* msg) {
  std::ofstream output_file(file.c_str(), std::ios::app) ;
  output_file << msg << std::endl;
}

void Cmyclass::set_file(std::string file) {
  this->file = file;
}

I use the ‘extern’ keyword in files that need access to the global:

extern Cmyclass myclass;

I would like to eliminate the set_file() method and set the file in the constructor:

Cmyclass::Cmyclass(std::string file) {
  this->file = file;
}

But if I do that, my extern usage above is no longer valid because of the parameters in the constructor. Is it possible to use the extern keyword if my constructor has parameters?

Thank you!

P.S. a little clearificatin here... please note that the code above works and that I instantiate the class elsewhere, but I want to modify my class so that the constructor takes parameters. If that is the case, how is my extern declaration supposed to look like?

Caroline Beltran
  • 888
  • 2
  • 9
  • 22
  • You can still define a default constructor without any parameters. Note that `extern Cmyclass myclass` is just a declaration. The true class instantiation happens elsewhere. – tonga Apr 09 '14 at 01:55
  • I am currently using a default constructor (the code above works) but I would like to use a constructor with parameters. If I add parameters to the constructor, my extern declaration above no longer works (I am guessing?? that the extern syntax above is only to be used for constructors with no parameters?) – Caroline Beltran Apr 09 '14 at 01:59
  • `extern Cmyclass myclass;` is not creating a Cmyclass object. It simply tells the linker to look for the (already created) object in another file. So, you can change the constructor the way you want. – 001 Apr 09 '14 at 02:00
  • @Johnny, but if I use the modified constructor (with params) above, how will my extern declaration look like? – Caroline Beltran Apr 09 '14 at 02:01
  • The same. Only your object definition reflects which constructor is called. BTW: You have one hidden somewhere in a `.cpp` file, right? – Deduplicator Apr 09 '14 at 02:02
  • You don't seem to really understand `extern`. [Read this to learn about it](http://stackoverflow.com/questions/1433204/how-do-i-share-a-variable-between-source-files-in-c-with-extern-but-how). – 001 Apr 09 '14 at 02:05
  • Johnny and Deduplicator were both right, constructor with params working perfectly with extern now. No anser to mark as correct though. – Caroline Beltran Apr 09 '14 at 02:15
  • Be careful using this design (static object for logging) because the order of initialization of static objects is unspecified. If you had another static object, there's no way to control whether that object's constructor runs before myclass's constructor or not. – M.M Apr 09 '14 at 02:23
  • @Matt McNabb, thank you for the warning. I do this with only a single instance of the class which I create immediately upon startup. I do use mutex during the write procedure by the way...but do you see any problem with using the global this way for logging? Thank you. – Caroline Beltran Apr 09 '14 at 02:41

1 Answers1

1

As indicated in the comments:

  • extern is a declaration not a definition. It just means that there's a global variable of that type.

So you have in some header file (e.g. Globals.h)

extern Cmyclass myclass;

Now, if you don't want your linker to fail, you must have in some source file (e.g. Globals.C)

Cmyclass myclass;

Now, the above calls the constructor without parameters. If you only have a constructor with parameters, you can replace that (in the source file) with:

Cmyclass myclass=Cmyclass("Some File");

... but the extern declaration remains the same. Think of it this way, other people don't care about how you created the myclass global variable, they're just interested in using it. So the fact that it has parameter-constructor or not only matters when the variable is instantiated (and that happens on the *.C, not on the *.h)

jsantander
  • 4,972
  • 16
  • 27