2011-07-10 165 views
0

可能重複:
What is an undefined reference/unresolved external symbol error and how do I fix it?解析的外部符號

我是比較新的C++(因爲你或許可以將問題告訴),我已經打了一個問題。我有兩個文件:Drives.h和Drives.cpp

Drives.h

#pragma once 

enum MountMode 
{ 
    User, 
    System, 
    Both, 
    Auto 
}; 

class Drive 
{ 
public: 
    Drive(void); 
    ~Drive(void); 

    BOOL Mount(MountMode mode); 
    VOID Unmount(void); 
    BOOL IsConnected(void); 

    static char* DeviceName; 
    static char* DrivePath; 
}; 

class Drives 
{ 
public: 
    Drives(void); 
    ~Drives(void); 
}; 

和我Drives.cpp:

#include "stdafx.h" 
#include "Drives.h" 

Drives::Drives(void) 
{ 
    Drive USB0; //Error happening here 
} 

Drives::~Drives(void) 
{ 
} 

錯誤是說,驅動器類的構造函數,析構函數和IsConnected()都是未解決的外部問題。我不知道,因爲我設置這個類像上cplusplus.com的一個提前

回答

4

隨着錯誤消息指出

感謝什麼我失蹤,你還沒有實現的Drive構造函數和析構函數:

Drive::Drive(void) { 
    ... 
} 

Drive::~Drive(void) { 
    ... 
} 

創建類類型的局部變量(如你在做Drive USB0;)將調用這個類的構造函數,和析構函數會在變量的作用域的末尾被調用;因此錯誤。

你也應該實現Drive的其他功能 - 在類聲明中聲明一個函數本質上是一個承諾,該函數將在某處實現。

3

是的,這些方法已經在頭文件中的Drive類中聲明過,但是實際上並沒有爲這些方法創建一個主體。

您必須在頭文件中內聯創建一個主體,在CPP文件中創建一個主體,或者確保您與定義這些方法的現有文件鏈接。否則,錯誤是正確的,這些方法尚未定義。

2

無法解析的外部符號錯誤通常是表示您提供了函數聲明,但未提供其定義。

在你的情況,因爲你宣佈Drive(void)~Drive(void)編譯器刪除其默認值,並預計您的定義存在,他們不這樣做,所以它拋出一個錯誤。

附註:使用void代替空括號表示「此函數不帶參數」是C風格定義,不應使用。

另外,不要使用#pragma once作爲包括警衛的替代品。它是一個Microsoft特定的構造,與其他編譯器不兼容。用實際包括代替後衛:


#ifndef CLASS_NAME_H 
#define CLASS_NAME_H 
//CODE HERE 
#endif 
+1

與其他編譯器不兼容?這實際上讓我發笑。 – Lockhead

+0

@Casey:'#pragma once'在叮噹聲,GCC,Intel,Borland等等時可以正常工作。稱它爲「微軟專用」肯定有點愚蠢。 – ildjarn

+1

@ildjarn:這仍然是非標準的。 – George

1

在下面的代碼聲明兩個類(DriveDrives),但只提供了一個(Drives

#pragma once 

enum MountMode 
{ 
    User, 
    System, 
    Both, 
    Auto 
}; 

class Drive 
{ 
public: 
    Drive(void); 
    ~Drive(void); 

    BOOL Mount(MountMode mode); 
    VOID Unmount(void); 
    BOOL IsConnected(void); 

    static char* DeviceName; 
    static char* DrivePath; 
}; 

class Drives 
{ 
public: 
    Drives(void); 
    ~Drives(void); 
}; 

爲了擺脫的實施錯誤消息,您必須包含Drive的類方法的實現。在方法來擴展你的Drives.cpp使你的代碼可能工作看起來像這樣:

#include "stdafx.h" 
#include "Drives.h" 

//Drive class constructor 
Drive::Drive(void) 
{ 
    //Add initialization code here. For example: 
    DeviceName = "Name"; 
    DrivePath = ""; 
} 

//Drive class destructor 
Drive::~Drive(void) 
{ 
} 

//Also add the implementation for Mount 
BOOL Drive::Mount(MountMode mode) 
{ 
    //implementation for Mount. For example: 
    return FALSE; 
} 

//Also add the implementation for Mount 
VOID Drive::Unmount() 
{ 
    //implementation for Unmount 
} 

//Also add the implementation for Mount 
BOOL Drive::IsConnected() 
{ 
    //implementation for IsConnected.For example: 
    return FALSE; 
} 


//Drives class constructor 
Drives::Drives(void) 
{ 
    Drive USB0; //Error happening here 
} 

//Drives class destructor 
Drives::~Drives(void) 
{ 
} 

也可以,如果你複製粘貼-D中的代碼,你也有對Drive類,但您的實現將它保存在另一個.cpp文件中,如Drive.cpp。在這種情況下,您應該將其他Drive.cpp文件中的所有實現方法複製到Drives.cpp。或者您應該將Drive課程的聲明從Drives.h移至Drive.h。在這種情況下,您將在不同文件中的班級之間有明確的分離,這很好,但您必須在Drives.h文件中包含Drive.h