c++中的部分正向声明

partial forward declaration in c++

本文关键字:声明 c++      更新时间:2023-10-16

我有一个项目(a)使用了另一个(B)中的一个类,但包含B的头会使a的编译非常混乱,而单独编译也可以(但在这种情况下,我不能在a中使用B的类)。

B是用VS2019的编译器v142编译的,A是用cuda 10的nvcc编译的。

如何仅转发声明几个成员,例如构造函数、属性和方法?

在A中,我想使用没有B标题的代码:

DX12Cuda = new DX12CudaInterop(ImUtil.ImFeatures.Width, ImUtil.ImFeatures.Height, L"DX12Cuda", funcMessage);
DX12Cuda->CuSurfaceUpdater = [&](cudaSurfaceObject_t o) {UpdateCuSurface(o); };
OnRenderDX12 = [&]() {DX12Cuda->OnRender(); };
DX12Cuda->OnInit(hwnd);

在B:

class DX12CudaInterop
{
public:
DX12CudaInterop(UINT width, UINT height, wstring name, MessageChangedCallback managedDelegate);
function<void(cudaSurfaceObject_t)> CuSurfaceUpdater;
OnInit(HWND hwnd);
OnRender();
}
void DX12CudaInterop::OnInit(HWND hwnd) {/*...*/}
void DX12CudaInterop::OnRender() {/*...*/}

错误示例:

严重性代码描述项目文件行禁止显示状态错误标识符"NPP_MIRROR_FLIP_ERR"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 412后跟"::"的错误名称必须是类或命名空间name ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 3
错误标识符"byte"为undefined ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 29
后面跟着"::"的错误名称必须是类或命名空间name ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 31
错误名称后面跟着"::"必须是类或命名空间name ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 41
错误应为";"ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 41
错误标识符"file"为未定义的ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 42
错误标识符"byte"为未定义的ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 52
函数声明中允许出现错误内联说明符只有ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 63
错误不完整类型不是allowed ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 63
错误标识符"ID3D12Object"为未定义的ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 63
错误标识符"pObject"为未定义的ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 63
错误应为")"ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 63
错误应为";"ShCuSum path_to_solution\D3D12CudaUpdateFull\DXSampleHelper.h 64
错误标识符"IDXGIFactory2"为未定义的ShCuSum path_to_solution\D3D12CudaUpdateFull\DX12CudaSample.h 30
错误标识符"IDXGIAdapter1"为未定义的ShCuSum path_to_solution\D3D12CudaUpdateFull\DX12CudaSample.h 30
错误标识符"NPP_BAD_ARG_Error"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 323错误标识符"NPP_COEFF_Error"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 326错误标识符"NPP_RECT_Error"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 329错误标识符"NPP_QUAD_Error"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 332错误标识符"NPP_MEM_ALLOC_ERR"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 335错误标识符"NPP_HISTO_NUMBER_OF_LEVELS_Error"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 338错误标识符"NPP_INVALID_INPUT"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 341错误标识符"NPP_POINTER_Error"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 344错误标识符"NPP_WARNING"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 347错误标识符"NPP_ODD_ROI_WARNING"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 350错误标识符"NPP_MEMFREE_ERR"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 403错误标识符"NPP_MEMSET_ERR"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 406错误标识符"NPP_MEMCPY_ERR"为未定义的ShCuSum路径_to_solution\D3D12CudaUpdateFull\helper_cuda.h 409错误(活动)E0135类"Microsoft::WRL::Details::EnableIf"没有成员"type"D3D12CudaUpdate C:\Program Files(x86)\Windows Kits\10\Include\10.0.18362.0\winrt\wrl\client.h 379

你不能。以下是你可以做的:

// interop.h, shared across the project
class iCudaInterop
{
public:
virtual ~iCudaInterop() { }
virtual void OnInit( HWND hwnd ) = 0;
virtual void OnRender() = 0;
};
extern std::unique_ptr<iCudaInterop> createInterop( UINT width, UINT height, const std::wstring& name, MessageChangedCallback del );
// interop.cpp, only in project B
#include "interop.h"
class CudaInterop : public iCudaInterop
{
DX12CudaInterop m_impl;
public:
CudaInterop( UINT width, UINT height, const std::wstring& name, MessageChangedCallback del ) :
m_impl( width, height, name, del ) { }
~CudaInterop() = default;
void OnInit( HWND hwnd ) override { m_impl.OnInit( hwnd ); }
void OnRender() override { m_impl.OnRender(); }
};
std::unique_ptr<iCudaInterop> createInterop( UINT width, UINT height, const std::wstring& name, MessageChangedCallback del )
{
return std::make_unique<CudaInterop>( width, height, name, del );
}

对于该属性,简单的方法是封装到iCudaInterop接口的两个更抽象的方法getter和setter中,在实现中获取/设置m_impl的字段。