【问题标题】:Unresolved External Symbol how to fix it? abstract class未解析的外部符号如何修复?抽象类
【发布时间】:2021-10-23 18:21:11
【问题描述】:

这是我的抽象类 Storestate.h:

#ifndef STORESTATE_H_
#define STORESTATE_H_

class Store;
class StoreState
{
public:
    virtual void Close(Store&);
    virtual void Open(Store&);
    virtual void Sell(Store&);
};

#endif

派生类头文件ConcreteStateOpened.h:

#ifndef CONCRETESTATEOPENED_H_
#define CONCRETESTATEOPENED_H_
#include "StoreState.h"
#include "Store.h"

class ConcreteStateOpened : public StoreState
{
public:
    ConcreteStateOpened() {}
    void Open(Store&) override;
    void Close(Store&) override;
    void Sell(Store&) override;
};

#endif

Dervied类cpp文件ConcreteStateOpened.cpp:

#include "ConcreteStateOpened.h"
#include <iostream>

using namespace std;

void ConcreteStateOpened::Open(Store &store)
{
    cout << store.Name << " is already opened!" << endl;
}
void ConcreteStateOpened::Close(Store &store)
{
    store.State = ConcreteStateOpened();
}
void ConcreteStateOpened::Sell(Store &store)
{
    std::cout << "Sell Opened";
}

我不知道如何解决这个问题。我尝试删除覆盖关键字以及虚拟关键字。甚至删除定义等。我只需要专业人士的帮助:,)

以下是未解决的外部符号错误:

1>ConcreteStateOpened.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Close(class Store &)" (?Close@StoreState@@UAEXAAVStore@@@Z)
1>Data.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Close(class Store &)" (?Close@StoreState@@UAEXAAVStore@@@Z)
1>StateStore.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Close(class Store &)" (?Close@StoreState@@UAEXAAVStore@@@Z)
1>ConcreteStateOpened.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Open(class Store &)" (?Open@StoreState@@UAEXAAVStore@@@Z)
1>Data.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Open(class Store &)" (?Open@StoreState@@UAEXAAVStore@@@Z)
1>StateStore.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Open(class Store &)" (?Open@StoreState@@UAEXAAVStore@@@Z)
1>ConcreteStateOpened.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Sell(class Store &)" (?Sell@StoreState@@UAEXAAVStore@@@Z)
1>Data.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Sell(class Store &)" (?Sell@StoreState@@UAEXAAVStore@@@Z)
1>StateStore.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall StoreState::Sell(class Store &)" (?Sell@StoreState@@UAEXAAVStore@@@Z)
1>D:\Local-Git-Repos\DesignPatterns\StateC++\StateStore\Debug\StateStore.exe : fatal error LNK1120: 3 unresolved externals

【问题讨论】:

    标签: c++ inheritance polymorphism abstract-class unresolved-external


    【解决方案1】:

    您没有使抽象基础中的方法成为纯虚拟的。 您还应该添加:公共虚拟析构函数、受保护的默认构造函数和删除复制/移动/赋值构造函数

    #ifndef STORESTATE_H_
    #define STORESTATE_H_
    
    class Store;
    class StoreState
    {
    public:
        virtual ~StoreState() = default;
        StoreState(const StoreState&) = delete;
        StoreState(StoreState&&) = delete;
        StoreState& operator=(const StoreState&) = delete;
    
        virtual void Close(Store&) = 0;
        virtual void Open(Store&) = 0;
        virtual void Sell(Store&) = 0;
    protected:
        StoreState() = default; // prevent accidental creation
    };
    
    #endif
    

    【讨论】:

      【解决方案2】:

      您的StoreState 实际上并不抽象。您已将 CloseOpenSell 声明为具有定义的实际虚函数。要在该类中声明一个没有定义的虚函数,请使用“纯虚”语法= 0

      此外,多态类类型最好有一个虚拟析构函数。根据五法则,当你声明一个析构函数时,一定要考虑复制/移动构造函数和复制/移动赋值。对于接口类,通常最好将其设为不可复制和不可分配。

      class StoreState
      {
      public:
          StoreState() = default;
          StoreState(const StoreState&) = delete;
          StoreState& operator=(const StoreState&) = delete;
          virtual ~StoreState() = default;
      
          virtual void Close(Store&) = 0;
          virtual void Open(Store&) = 0;
          virtual void Sell(Store&) = 0;
      };
      

      【讨论】:

        【解决方案3】:

        首先,您提供的代码中没有抽象类,因为类StoreState 不包含纯虚函数。

        来自 C++ 20 标准(11.7.3 抽象类)

        2 虚函数通过使用指定为纯虚函数 类中函数声明中的纯说明符(11.4) 定义。 [注意:这样的功能可能会被继承:见下文。 — end note] 一个类是一个抽象类,如果它至少有一个纯 虚函数。 [注意:抽象类只能用作 其他类的基类;抽象类的任何对象都不能 除了作为从它派生的类的子对象(6.2、11.4)之外创建。 — end note] 纯虚函数只有在调用时才需要定义, 或与 (11.4.6) 一样,限定 ID 语法

        您需要提供在StoreState 类中声明的虚函数的定义,或者将它们设为纯虚函数,例如

        class StoreState
        {
        public:
            virtual void Close(Store&) = 0;
            virtual void Open(Store&) = 0;
            virtual void Sell(Store&) = 0;
        };
        

        即使函数被声明为纯虚函数,但如果需要,您也可以提供其定义(在声明为纯虚函数的类定义之外)。

        请注意,当您拥有多态类时,您应该将析构函数也声明为虚拟的。例如

        class StoreState
        {
        public:
            virtual ~StoreState() = default;
        
            virtual void Close(Store&) = 0;
            virtual void Open(Store&) = 0;
            virtual void Sell(Store&) = 0;
        };
        

        【讨论】:

          【解决方案4】:

          您可能需要将 virtual 添加到具体的类方法中

          #ifndef CONCRETESTATEOPENED_H_
          #define CONCRETESTATEOPENED_H_
          #include "StoreState.h"
          #include "Store.h"
          
          class ConcreteStateOpened : public StoreState
          {
          public:
              ConcreteStateOpened() {}
              virtual void Open(Store&) override;
              virtual void Close(Store&) override;
              virtual void Sell(Store&) override;
          };
          
          #endif
          

          【讨论】:

          • 不,只要派生类中的函数与基类虚函数具有相同的名称和签名,无论virtual 和/或override 是否为展示。而且由于 override 声明不可能不是虚拟的,因此许多 C++ 程序员还认为编写 virtual 是多余的。
          猜你喜欢
          • 2019-02-26
          • 2018-05-23
          • 1970-01-01
          • 1970-01-01
          • 2020-02-15
          • 2011-01-10
          • 2013-05-25
          • 2011-08-12
          相关资源
          最近更新 更多