【发布时间】:2016-07-27 03:31:18
【问题描述】:
我正在设计一个接口来抽象管理 Direct3D、Direct2D、DXGI 和相关 Win32API 调用的任务。
将所有内容保存在命名空间中或重构以使用类?
WindowsApp.h
#pragma once
#include <Windows.h>
namespace WindowsApp
{
bool Initialize(HINSTANCE instanceHandle);
}
WindowsApp.cpp
#include "WindowsApp.h"
namespace WindowsApp
{
namespace
{
HWND ghMainWnd = 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
break;
default:
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
}
bool Initialize(HINSTANCE instanceHandle)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = instanceHandle;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = L"BasicWndClass";
if (!RegisterClass(&wc))
{
MessageBox(0, L"RegisterClass FAILED", 0, 0);
return false;
}
ghMainWnd = CreateWindow(
L"BasicWndClass",
L"Win32Basic",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
instanceHandle,
0);
if (ghMainWnd == 0)
{
MessageBox(0, L"CreateWindow FAILED", 0, 0);
}
ShowWindow(ghMainWnd, 1);
UpdateWindow(ghMainWnd);
return true;
}
}
Main.cpp
#include "WindowsApp.h"
int Run()
{
MSG msg = { 0 };
BOOL bRet = 1;
while ((bRet = GetMessage(&msg, 0, 0, 0)) != 0)
{
if (bRet == -1)
{
MessageBox(0, L"GetMessage FAILED", L"Error", MB_OK);
break;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Deinitialize Here
return (int)msg.wParam;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd)
{
if (!WindowsApp::Initialize(hInstance)) { return 0; }
return Run();
}
使用命名空间允许我在嵌套的未命名命名空间内隐藏实现细节。 一个类不会让我隐藏东西,但我可以让它们在私有部分中无法访问,我想这已经足够了。
使用类存在用户尝试实例化多个对象的风险,这会导致应用程序因两次初始化 DirectX 或其他原因而崩溃。
命名空间避免了这个问题,但是它们会降低性能,我必须在每个函数调用期间检查 Initialized 变量。我真的不喜欢这个。
最后,使用类要求用户在整个应用程序中需要底层方法的地方传递实例化对象。这真是令人失望,因为每当我在一个文件中时,命名空间方法让我可以访问,该文件有一个 #include 到命名空间头文件。我真的很喜欢这个。
命名空间方法似乎是最好的方法,但在嵌套的未命名命名空间内处理变量的方式中,有些东西并不适合我。 这样可以吗?我的直觉告诉我不行!不!不!
所以我想我的问题是:这是命名空间的合适用例吗?
澄清: 我在 WindowsApp.cpp 中定义了未命名的命名空间以及函数定义——所有函数的前向声明都在 WindowsApp.h 中——通过调用这些函数来操纵未命名命名空间内的变量。这是对命名空间的不当使用还是应该以不同的方式完成?只需将头文件包含在任何其他 .cpp 中,您就可以访问函数,进而访问基础数据。这是非常吸引人的。我的直觉告诉我,这样的结构会导致某种性能损失。
【问题讨论】:
-
听起来你在寻找单例模式
-
乍一看确实如此。这种命名空间模式听起来像是更好的方法,我可以大声声明嵌套未命名命名空间内的变量,然后通过父命名命名空间内定义的函数访问它们。当您只需
#include包含对其中命名空间函数的所有前向声明的文件时,不必为了访问它的成员函数而在应用程序周围传递一个实例化的类对象似乎是不必要的。 -
你不必到处传递一个实例,单个实例可以静态获取
WindowsAppClass::getInstance()
标签: c++ class namespaces