Search code examples
c++inheritancepolymorphismfinal

C++ Final class with polymorphism


I have an abstract class which defines the basic functionality of a submodule for my application. Let's call this abstract class IProdBridge.

IProdBridge contains virtual and non-virtual methods and also some pure-virtual methods.

Because this software runs on a multitude of different platforms, the base class handles most of the functionality, while its specialisations handle the platform-specific functionality (e.g. handling of endianness on certain platforms).

Let's call the specialised class TgurProdBridge.

Simply deriving from the base class IProdBridge works just fine, however I want to mark the specialised class as final, so it may not be overridden in the future.

Maybe I'm just having a massive brain fart right now, but this is what my specialised class definition looks like:

class TgurProdBridge final: public IProdBridge {
                                           // ^ error: expected class-name before ‘{’ token
        public: // +++ Static +++
            static TgurProdBridge& getInstance(milliseconds loopInterval = milliseconds(-1), ProdResponseCallback callback = {},
                                             json settings = "{}"_json, LogLevel logLevel = LOGLEVEL_MAXVALUE, string logPath = "") {
                static TgurProdBridge* instance = nullptr;

                if (instance == nullptr) {
                    if (loopInterval == DEFAULT_MS || !callback || settings.empty() || logLevel == LOGLEVEL_MAXVALUE || logPath.size() == 0) {
                        throw getSysError(0xbada79, "Invalid arguments passed for object instantiation! Did you set all the arguments?");
                    }

                    instance = new TgurProdBridge(loopInterval, callback, settings, logLevel, logPath);
                }

                return instance;
            }

        public: // +++ Destructor +++
            ~TgurProdBridge() {  }

        private: // +++ Constructor / Destructor +++
            TgurProdBridge(milliseconds loopInterval, ProdResponseDataCallback callback, json settings, LogLevel logLevel, string logPath):
            IProdBridge(loopInterval, callback, settings) {
                getLoggerInstance() = new ConsoleLogger(__FUNCTION__, logLevel, true, 0, true, true, logPath, 128);
                getLoggerInstance()->setCurrentApplicationName(__FUNCTION__);
                getLoggerInstance()->setCurrentLoggerFormat(
                    "[[    \033[1;34m%s\033[0m   ]] [%s] [%s] %s",
                    ILogger::LOG_FMT_APPNAME.c_str(), 
                    ILogger::LOG_FMT_DATETIME.c_str(),
                    ILogger::LOG_FMT_LOGLVL.c_str(),
                    ILogger::LOG_FMT_MSG.c_str()
                );
            }

        private: // +++ Const Static (Defaults) +++
    };

For some reason my compiler (g++ 6) is throwing the following error:

error: expected class-name before ‘{’ token
     class TgurProdBridge final: public IProdBridge {
                                                    ^

I'm compiling with C++ 14 support.

Why am I getting this issue? I should be able to mark a specialised class as final; otherwise the final keyword wouldn't make any sense.


Solution

  • I've found the error

    This is probably one of the worst cases of PEBKAC, but maybe this will save someone else from searching as long as I have.

    I'm not entirely sure why this didn't cause a plethora of other compiler errors, but the issue was with my namespace.

    This class is nested within two namespaces:

    namespace MyApp { namespace ProdBridge {
    
        class ...
    
    } /* namespace ProdBridge */ } /* namespace MyApp */
    

    However, instead of that my namespaces looked like this:

    namespace { namespace ProdBridge {
    
        class ...
    
    } /* namespace ProdBridge */ } /* namespace MyApp */
    

    Why removing the final keyword "fixed" this error is beyond me. Sorry for the waste of your time 🙃