2

I need to deep copy an appender in log4cxx however every appender has a private copy constructor and operator= so I can't do anything. At the same time I can call the method newInstance to create a default instance of the same class. How can I replace a long if instanceof statements in this case? Just an example:

class FileAppender {
public:
    FileAppender();
    ~FileAppender();
    ...getter.....
    ...setter.....
protected:
    ....few variables....
private:
    FileAppender(const FileAppender& o);
    FileAppender& operator=(const FileAppender& o);
}

class RollingFileAppender: public FileAppender {
public:
    RollingFileAppender();
    ~RollingFileAppender();
    ...getter.....
    ...setter.....
protected:
    ....few variables....
private:
    RollingFileAppender(const RollingFileAppender& o);
    RollingFileAppender& operator=(const RollingFileAppender& o);
}

What I have now:

if ((*it)->instanceof(RollingFileAppender::getStaticClass())) {
   //cast, create new instance and copy using getter and setter
} else if ((*it)->instanceof(FileAppender::getStaticClass())) {
   //cast, create new instance and copy using getter and setter
}
......and so on........

How can I replace the if instanceof? Usually I use a visitor pattern but I can't change the library.

greywolf82
  • 21,813
  • 18
  • 54
  • 108
  • The members in question being private might mean they are not implemented at all. Copying obviously is not supported, most likely due to file access issues (trying to open the same file multiple times). So question now is: Why do you want/need this at all? Couldn't you just share a pointer, possibly protected against race conditions if in multi-threaded environment? – Aconcagua Aug 06 '18 at 08:40
  • @Aconcagua Because I need to use as "template". I mean: you assign a file appender to a logger "x", every new child logger "x.N" will log on a different file but I'd like to set the properties of child loggers as the parent logger. – greywolf82 Aug 06 '18 at 08:47
  • And indepent file logger parents might be parametrised differently? If not, a factory method initialising the members as desired might be better approach. – Aconcagua Aug 06 '18 at 08:51
  • I'd like to have freedom to set any kind of appender on the parent, but in case of a file appender, the parent won't have a file parameter set, indeed in the code every child will get the parent and if a file appender will clone the properties and will set a file name unique for each child. – greywolf82 Aug 06 '18 at 08:54
  • Don't really get it... Staying with what we have so far, what's the matter with instanceof, why replace it at all? If, have you tried `dynamic_cast`? – Aconcagua Aug 06 '18 at 09:03
  • Just to have shorter code, a long list of if or dynamic_cast it's not really the best thing you can have in your code. I'm just wondering if I could do something better, as I said, usually I use a visitor in this case but I can't do it because I can't change the library – greywolf82 Aug 06 '18 at 09:05
  • Ah, I see, not replace the single instanceof, but the if-else-sequence... No, I don't see a way to have it shorter. You'd need a virtual function in in the log4c++ classes themselves, something like `createCopy(...)`, but that's not available. Even if it was, you'd still have the problem that different appender types might require different parameters (especially new file name for FileAppenders), and then we are back at where we are already (perhaps some if's less)... – Aconcagua Aug 06 '18 at 09:17
  • You might get the *bodies* shorter, though (avoiding duplicate code), profiting from the inheritance hierarchy of the appenders: `if(FileAppender) { /* copy common parameters */ if(RollingFileAppender) { /* specific parameters */ } }` – Aconcagua Aug 06 '18 at 09:20
  • Can you post the actual code performing the copy for the appenders? – ceztko Mar 26 '19 at 14:27

0 Answers0