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.
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 🙃