Search code examples
c++namespacesabstract-class

How to make an alias for the class from internal namespace?


There is a parent class in my app:

platform/common/baseapp.hpp:

#pragma once

#include <string>

namespace platform::common 
{

class BaseApp
{
    public:
        BaseApp(std::string name);
        virtual ~BaseApp() {}
        virtual int run() = 0;
    private:
        std::string m_name;
};

}

platform/common/baseapp.cxx:

#include "baseapp.hpp"

using namespace platform::common;

BaseApp::BaseApp(std::string name):
    m_name(std::move(name))
{
    
}

And an implementation for macOS:

platform/darwin/app.hpp:

#pragma once

#include <string>

#include "platform/common/baseapp.hpp"

namespace platform::darwin 
{

class DarwinApp: public platform::common::BaseApp 
{
    public:
        DarwinApp(std::string name);
        int run() override;
};

}

platform/darwin/app.cxx:

#include "app.hpp"

using namespace platform::darwin;

DarwinApp::DarwinApp(std::string name):
    BaseApp(std::move(name))
{

}

int DarwinApp::run() {
    return 0;
}

Also an alias to call from main():

platform/platform.hpp:

#include "flags.hpp"

namespace platform {

#if TARGET_APPLE_MACOS //It's a custom valid flag
    #include "platform/darwin/app.hpp"
    
    typedef platform::darwin::DarwinApp App;
#endif

}

Finally I create an instance in main():

main.cxx:

#include <string>

#include "platform/platform.hpp"

using namespace platform;

int main() {
    App app(std::string("App"));
    return app.run();
}

However, when I try to build my app it crashes with errors:

build] ld: Undefined symbols:
[build]   platform::platform::darwin::DarwinApp::run(), referenced from:
[build]       _main in main.cxx.o
[build]   platform::platform::darwin::DarwinApp::DarwinApp(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>), referenced from:
[build]       _main in main.cxx.o
[build] clang: error: linker command failed with exit code 1 (use -v to see invocation)

The problem is obviously due to namespaces, there is platform::platform. But I can't get how to fix it.


Solution

  • You included the header file within a namespace in platform.hpp. You should move it out of it:

    #include "flags.hpp"
    
    #if TARGET_APPLE_MACOS //It's a custom valid flag
    #include "platform/darwin/app.hpp"
    
    namespace platform {
        typedef darwin::DarwinApp App;
    }
    #endif
    

    Furthermore, being inside namespace platform, you don't need to repeat it in the typedef.