C++ 未解析外部符号

C++ 未解析外部符号,c++,class,C++,Class,可能重复: 我对C++比较新(你可以通过这个问题来判断),我碰到了一个问题。我有两个文件:Drives.h和Drives.cpp 驱动器 #pragma once enum MountMode { User, System, Both, Auto }; class Drive { public: Drive(void); ~Drive(void); BOOL Mount(MountMode mode); VOID Unmou

可能重复:

我对C++比较新(你可以通过这个问题来判断),我碰到了一个问题。我有两个文件:Drives.h和Drives.cpp

驱动器

#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);
};
和my Drives.cpp:

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

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

Drives::~Drives(void)
{
}
错误是说驱动器类构造函数、析构函数和IsConnected()都是未解析的外部对象。我不确定我错过了什么,因为我在cplusplus.com上设置了这个类


提前感谢

正如错误消息所说,您尚未实现
驱动器的构造函数和析构函数

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

Drive::~Drive(void) {
    ...
}
创建类类型的局部变量(就像您在
Drive USB0;
中所做的那样)将调用该类的构造函数,而析构函数将在变量作用域的末尾调用;因此出现了错误


您还应该实现驱动器的其他函数-在类声明中声明函数本质上是承诺函数将在某个地方实现。

是的,这些方法已经在头文件的驱动器类中声明,但您实际上还没有为这些方法创建主体


必须在头文件中内联创建主体,在CPP文件中创建主体,或者确保链接到定义这些方法的现有文件。否则,错误是正确的,这些方法尚未定义。

未解决的外部符号错误通常表示您提供了函数声明,但未提供其定义

在您的例子中,由于您声明了
Drive(void)
~Drive(void)
,编译器将删除其默认值,并希望您的定义存在,而它们不存在,因此它会抛出一个错误

作为旁注:使用
void
代替空括号表示“此函数不带参数”是C风格的定义,不应使用

另外,不要使用
#pragma一次
代替include-guard。它是Microsoft特定的构造,与其他编译器不兼容。使用实际包含防护装置:


#ifndef类别名称
#定义类名称
//代码在这里
#恩迪夫

在下面的代码中,您声明了两个类(
驱动器
驱动器
),但您只为一个(
驱动器
)提供了实现

要消除错误消息,必须包含驱动器类方法的实现。扩展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)
{
}

如果复制paste-d代码,也可能有
Drive
类的实现,但将其保存在另一个.cpp文件中,如
Drive.cpp
。在这种情况下,您应该将所有实现方法从另一个
Drive.cpp
文件复制到
Drives.cpp
。或者您应该将
Drive
类的声明从
Drives.h
移动到
Drive.h
。在这种情况下,不同文件中的类将有明确的分隔,这很好,但必须在
Drives.h
文件中包含
Drive.h

与其他编译器不兼容吗?这真的让我笑了。@Casey:
#pragma once
对clang、GCC、Intel、Borland等都很好。称它为“特定于Microsoft”肯定有点傻。@ildjarn:它仍然是非标准的。@George:我没有说它是标准的,只是说它不是特定于Microsoft的,而且它与大多数其他编译器兼容。
#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)
{
}