无法在派生的子命名空间中实现方法 Class
Can't Implement Method in Subnamespace For Derived Class
具有嵌入式 C 经验的 Dotnet 开发人员进入 cpp 领域,让您了解我的 experience/knowledge。
我在 src/Core/Window/
中有一个 class Window
基地:
namespace Pyrite::Core::Window
{
class PYR_API Window
{
public:
using EventCallbackFn = std::function<void(Pyrite::Event&)>;
virtual ~Window();
virtual void OnUpdate();
virtual uint32_t GetWidth() const = 0;
virtual uint32_t GetHeight() const = 0;
virtual void SetEventCallback(const EventCallbackFn& callback) = 0;
virtual void SetVSync(bool isEnabled) = 0;
virtual bool IsVSyncEnabled() const = 0;
static Window* Create(const WindowProperties& props = WindowProperties());
};
}
据此,我为特定于平台的 WindowsWindow
创建了一个派生的 class,我想将其存储在 src/Core/Window/Platform/
:
namespace Pyrite::Core::Window::Platform
{
class WindowsWindow : public Pyrite::Core::Window::Window
{
public:
WindowsWindow(const WindowProperties& properties);
virtual ~WindowsWindow();
void OnUpdate() override;
inline uint32_t GetWidth() const override { return m_Data.Width; }
inline uint32_t GetHeight() const override { return m_Data.Height; }
inline void SetEventCallback(const EventCallbackFn& callback) override { m_Data.EventCallback = callback; }
void SetVSync(bool isEnabled) override { m_Data.VSyncEnabled = isEnabled; }
bool IsVSyncEnabled() override {return m_Data.VSyncEnabled; }
private:
virtual void Init(const WindowProperties& properties);
virtual void Close();
GLFWwindow* m_Window;
struct WindowData
{
std::string Title;
uint32_t Width, Height;
bool VSyncEnabled;
EventCallbackFn EventCallback;
};
WindowData m_Data;
};
}
但是,在 WindowsWindow.cpp
中,当我尝试为 Window::Create()
创建我的实现时,我收到一条关于无法在此处定义它的错误消息:
namespace Pyrite::Core::Window::Platform
{
static bool s_GLFWInitialised = false;
Window* Window::Create(const WindowProperties& properties)
{
return new WindowsWindow(properties);
}
}
'Pyrite::Core::Window::Window *Pyrite::Core::Window::Window::Create(const Pyrite::Core::Window::WindowProperties &)': symbol cannot be defined within namespace 'Platform' PyriteEngine C:\repos\Pyrite\PyriteEngine\src\Core\Window\Platform\WIndowsWindow.cpp 9
当我调整命名空间使它们都位于 Pyrite::Core::Window
中时,它似乎消失了......但是,我无法在子命名空间中定义它,这对我来说似乎很奇怪。我希望我的命名空间尽可能遵循我的文件夹结构(因为这几乎是我习惯的,它使事情保持逻辑和整洁)并且将平台特定的东西隐藏在子命名空间中对我来说似乎很有意义。
这只是我无法做到的事情还是我在这里遗漏了什么?
首先,C++ 中的源文件和命名空间之间的分离是一个特性,因为它们可以 在适当的情况下遵循相同的结构,但其他组织也是可能的。除此之外,不可能(按字面意思)做你要求的,因为它会产生奇怪的 “兄弟姐妹” 用于名称查找,被认为更麻烦比他们的价值。特别是,给定
namespace A {
int i;
struct X {void f(); void g(); void h();};
namespace B {
void g();
namespace C {
int i;
void h();
void X::f() {g(); h(); ++i;} // pretend this is OK
}
}
}
尚不完全清楚 B::g
and/or C::h
是否比 X::g
或 X::h
“更接近” X::f
的定义.也不清楚是否需要将 X::f
的定义移入或移出 class 发现的 i
变化。
您通常可以使用 using-declarations 来解决这些限制:上面的 X
可能在 B
中定义,但 在A
(或C
!)中暴露。有时受影响的成员函数也可以移动到属于不同命名空间的 base class。
具有嵌入式 C 经验的 Dotnet 开发人员进入 cpp 领域,让您了解我的 experience/knowledge。
我在 src/Core/Window/
中有一个 class Window
基地:
namespace Pyrite::Core::Window
{
class PYR_API Window
{
public:
using EventCallbackFn = std::function<void(Pyrite::Event&)>;
virtual ~Window();
virtual void OnUpdate();
virtual uint32_t GetWidth() const = 0;
virtual uint32_t GetHeight() const = 0;
virtual void SetEventCallback(const EventCallbackFn& callback) = 0;
virtual void SetVSync(bool isEnabled) = 0;
virtual bool IsVSyncEnabled() const = 0;
static Window* Create(const WindowProperties& props = WindowProperties());
};
}
据此,我为特定于平台的 WindowsWindow
创建了一个派生的 class,我想将其存储在 src/Core/Window/Platform/
:
namespace Pyrite::Core::Window::Platform
{
class WindowsWindow : public Pyrite::Core::Window::Window
{
public:
WindowsWindow(const WindowProperties& properties);
virtual ~WindowsWindow();
void OnUpdate() override;
inline uint32_t GetWidth() const override { return m_Data.Width; }
inline uint32_t GetHeight() const override { return m_Data.Height; }
inline void SetEventCallback(const EventCallbackFn& callback) override { m_Data.EventCallback = callback; }
void SetVSync(bool isEnabled) override { m_Data.VSyncEnabled = isEnabled; }
bool IsVSyncEnabled() override {return m_Data.VSyncEnabled; }
private:
virtual void Init(const WindowProperties& properties);
virtual void Close();
GLFWwindow* m_Window;
struct WindowData
{
std::string Title;
uint32_t Width, Height;
bool VSyncEnabled;
EventCallbackFn EventCallback;
};
WindowData m_Data;
};
}
但是,在 WindowsWindow.cpp
中,当我尝试为 Window::Create()
创建我的实现时,我收到一条关于无法在此处定义它的错误消息:
namespace Pyrite::Core::Window::Platform
{
static bool s_GLFWInitialised = false;
Window* Window::Create(const WindowProperties& properties)
{
return new WindowsWindow(properties);
}
}
'Pyrite::Core::Window::Window *Pyrite::Core::Window::Window::Create(const Pyrite::Core::Window::WindowProperties &)': symbol cannot be defined within namespace 'Platform' PyriteEngine C:\repos\Pyrite\PyriteEngine\src\Core\Window\Platform\WIndowsWindow.cpp 9
当我调整命名空间使它们都位于 Pyrite::Core::Window
中时,它似乎消失了......但是,我无法在子命名空间中定义它,这对我来说似乎很奇怪。我希望我的命名空间尽可能遵循我的文件夹结构(因为这几乎是我习惯的,它使事情保持逻辑和整洁)并且将平台特定的东西隐藏在子命名空间中对我来说似乎很有意义。
这只是我无法做到的事情还是我在这里遗漏了什么?
首先,C++ 中的源文件和命名空间之间的分离是一个特性,因为它们可以 在适当的情况下遵循相同的结构,但其他组织也是可能的。除此之外,不可能(按字面意思)做你要求的,因为它会产生奇怪的 “兄弟姐妹” 用于名称查找,被认为更麻烦比他们的价值。特别是,给定
namespace A {
int i;
struct X {void f(); void g(); void h();};
namespace B {
void g();
namespace C {
int i;
void h();
void X::f() {g(); h(); ++i;} // pretend this is OK
}
}
}
尚不完全清楚 B::g
and/or C::h
是否比 X::g
或 X::h
“更接近” X::f
的定义.也不清楚是否需要将 X::f
的定义移入或移出 class 发现的 i
变化。
您通常可以使用 using-declarations 来解决这些限制:上面的 X
可能在 B
中定义,但 在A
(或C
!)中暴露。有时受影响的成员函数也可以移动到属于不同命名空间的 base class。