C ++类:概念类Doppelganger:LNK2005

时间:2014-08-31 19:37:26

标签: c++ class data-structures preprocessor-directive lnk2005

啧。我在定义课程时遇到了臭名昭着的LNK2005错误,我似乎无法解决问题。

(我正在撕裂一个同样臭名昭着的单身人士以反映出来,组织。)最初说的单身人士被编码......以这种分歧,精彩的方式...以避免所有的C ++ OPP原则和概念当时我一无所知,但它有效! ....不知何故。虽然它做了一些最简单的C ++概念。现在我需要组织,编译速度和高级结构化技术,以使其快速工作,并且 - 你得到它。

A-无论如何。分开后,不得不改写一些,我注意到了必要性。我必须声明多个.cpp文件只是因为编译器被双重声明和通常的头类定义大量激励。

此外,我已经相应地使用了预处理程序指令。但仍然存在一些问题。

注意(编辑):我已经重写了提出错误的问题。

考虑:

D3D.h

#include "Infinity.h"
class Direct3D :
public Infinity
{
public:
    Direct3D();
    ~Direct3D();
    IDXGISwapChain                  *Swapchain; //Display modes.
    static ID3D11Device             *Device;
    static ID3D11DeviceContext      *DeviceContext;
    static ID3D11RenderTargetView   *RenderTargetView;

    void D3D_Start(float width, float height);
    void D3D_Render();
    void D3D_Terminate();
    void ViewPort(float Height, float Width, float MaxDepth, float MinDepth, float TopLeftX, float TopLeftY);
}Direct3D;

...和Windows.h

#include "Infinity.h"
class Windows :
public Infinity
{
    public:
    Windows();
    ~Windows();
    bool DisplayWindow(int width, int height, HINSTANCE hInstance);
    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
}Windows;

最后,Infinity.h

#pragma once

class Infinity{
public:
Infinity();
~Infinity();

static HWND hWnd;
};

而所有实现都在各自的.cpp文件中。除了#pragma之外,我还使用了#ifndef ... #endif。我怀疑我可能无意中通过自动初始化头文件中的类来调用某种实现。但它看起来非常犹太,并允许我将函数成员声明为:

Direct3D.D3D_Start()没有说明静态成员Direct3D::D3D_Start()。 我的标题都应该是静态的吗?

编辑:下面是.cpp文件:

#include "stdafx.h"
#include "Infinity.h"
#include "Windows.h"
#include "Direct3D.h"

MSG     msg;
float width = 1024;
float height = 768;

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    windows.DisplayWindow(1280, 900, hInstance);
    direct3D.D3D_Start(width, height);
    direct3D.ViewPort(height, width, 1.0f, 0.0f, 0, 0);
    while (WM_QUIT != msg.message){
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else{
            direct3D.D3D_Render();
        }
    }
    direct3D.D3D_Terminate();
    return msg.wParam;
}

*更新.cpp已更改为显示Niall的解决方案。 编辑:

问题:

我是否收到了LNK2005问题,因为我在其头文件中自动初始化了我的类,考虑到Stack Overflow问题的解决方案:

VS 2010 C++ LNK2005 errors while using #pragma once and #ifndef

根据我对解决方案的理解,这似乎不起作用。

编译器

VS2013返回:

Error 1 error LNK2005: "class Direct3D Direct3D" (?Direct3D@@3V0@A) already defined in Direct3D.obj C:\Users\InfinityMachine\documents\visual studio 2013\Projects\Win32Project3\Win32Project3\Win32Project3.obj Win32Project3

Error 2 error LNK2005: "class Windows Windows" (?Windows@@3V0@A) already defined in Win32Project3.obj C:\Users\InfinityMachine\documents\visual studio 2013\Projects\Win32Project3\Win32Project3\Windows.obj Win32Project3

Error 3 error LNK1169: one or more multiply defined symbols found C:\Users\InfinityMachine\documents\visual studio 2013\Projects\Win32Project3\Debug\Win32Project3.exe 1 1 Win32Project3

1 个答案:

答案 0 :(得分:0)

您立即声明class Direct3D... } Direct3D;和同名变量。这可能是造成这种错误的原因。

名为Direct3D(或其他)的Direct3D类型的变量将位于包含该标头的每个翻译单元中,同样适用于Windows

一种可能的解决方案是删除变量声明,另一种可能是移动它并使其静态,或者在匿名命名空间中。替代包括extern或实施单身人士;这可能更接近原意。

根据进一步的讨论,这里有一个合适的解决方案;

class Direct3D {}; 
extern Direct3D direct3D;

然后在其中一个实现文件中

Direct3D direct3D;

然后将对象声明为extern并提供它的单个实例。