0

This question might get downvoted because its overly simple - but I am not sure of the pattern I am supposed to be following for these kinds of objects.

I would like to store an instance of a log4cpp logger in a class so I only need to instantiate it once. This, in my mind, is going to help me keep my code clean.

Imagine I have a class like so:

#include <log4cpp/Category.hh>
#include <log4cpp/Appender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/Layout.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/Priority.hh>

class ExampleClass {
private:
    log4cpp::Category& logger;

public:
    ExampleClass();
   ~ExampleClass();
}

With implementation:

ExampleClass::ExampleClass() {
    log4cpp::Appender *appender1 = new log4cpp::OstreamAppender("console", &std::cout);
    appender1->setLayout(new log4cpp::BasicLayout());

    log4cpp::Appender *appender2 = new log4cpp::FileAppender("default", "output.log");
    appender2->setLayout(new log4cpp::BasicLayout());

    logger = log4cpp::Category::getRoot();
    logger.setPriority(log4cpp::Priority::WARN);
    logger.addAppender(appender1);
    logger.addAppender(appender2);

}

According to the the documentation (http://log4cpp.sourceforge.net/#simpleexample) the function log4cpp::Category::getRoot() returns a log4cpp::Category&. So naturally I'd like to store this (as shown above).

Unfortunately, this does not work. I get the following error from my IDE: operator = is a private member of log4cpp::Category. Now i've realized I've gotten in over my head. I'm confused, especially considering the class documentation (http://log4cpp.sourceforge.net/api/classlog4cpp_1_1Category.html) seems to indicate what I've done here is correct.

I'd imagine that I've screwed up my understanding of pointers here (why am I passing around addresses via & rather than a pointer via indirection). Could someone explain to me how I can fix this up/where I have gone wrong?

Thank you!

walnut
  • 21,629
  • 4
  • 23
  • 59
CL40
  • 579
  • 1
  • 5
  • 12
  • Does this answer your question? [How to initialize the reference member variable of a class?](https://stackoverflow.com/questions/15403815/how-to-initialize-the-reference-member-variable-of-a-class) – walnut Oct 31 '19 at 00:50
  • The error message does not really make sense in the context. Are you sure your wrote `log4cpp::Category& logger;` and not `log4cpp::Category logger;`? If you really want a reference member here, then the duplicate I linked applies. – walnut Oct 31 '19 at 00:52
  • The way you formulated your question seems to indicate to me that you are not aware of what a reference (the `&` after a type name) is. If that is the case, you should really start learning about that first. References are not pointers and `&` is not the address-of-operator in this context. References should be covered (probably before pointers) in a [good introductory C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – walnut Oct 31 '19 at 00:58
  • @uneven_mark it turns out the problem was I didn't realize you had to initialize references in the initializer list. The duplicate linked is the solution to my problem (I missed a reference when I transcribed the code here in the class definition, but in my code it existed). It wasn't so much a lack of understanding of pointers, but not being a professional C++ programmer I haven't dealt much with being given a reference (im guessing its static in the logger?) so this type of passing confused me. If you mark it duplicate or post an answer I'll mark it complete. – CL40 Oct 31 '19 at 01:05
  • `getRoot` seems to return a singleton. I would advice against saving a reference to it. Instead just call `getRoot` each time you need it. Also this library is very old and doesn't seem to have had any API overhauls in the last decade. Requiring you to `new` raw pointers to pass them to functions which take ownership of them is not something you would do in modern C++. I'd advice you to look for a more modern library, that is at least targeted towards C++11 or later. – walnut Oct 31 '19 at 01:08
  • Knowing how references work is much more important in C++ than knowing how pointers work. The only reason you are seeing all these pointers and `new` calls here is because the library was designed against the C++ standard from 1998, that shouldn't be used anymore, if possible. – walnut Oct 31 '19 at 01:10
  • I already flagged the question as duplicate. I don't have enough reputation to vote to close. Some higher-rep user will do that. – walnut Oct 31 '19 at 01:18

0 Answers0