在c++中实现工厂模式

Implementing Factory Pattern in C++

本文关键字:工厂 模式 实现 c++      更新时间:2023-10-16

我基本上有标题问题。

#include "Base.h"
class Factory
{
    public:
        static Base generateReply(int input);
};

然后是工厂cxx文件

#include "derived1.h"
#include "Factory.h"
Base Factory::generateReply(int input)
switch(input)
{
    case(0):
      return Base();
    case(1):
      return derived1();
    .....
}

然后是基类头文件

class Base
{
   protected:
       std::string type;
   public:
       Base(){};
       Base(std::string in);
       virtual std::string doStuff();
}

还有cxx文件

#include "Base.h"
Base::Base(std::string in)
{
    type = in;
}

,然后派生一个类

#include "Base.h"
class derived1: public Base
{
    public:
       derived1();
       derived1(std::string in) : Base(in){};
       std::string doStuff();
}

后面跟着它的CXX文件

#include "derived1.h"
std::string derived1::doStuff()
{
  return type;
}

现在每个单独的组件都编译得很好。当我试图把所有事情联系在一起时,一切都错了。我得到像

这样的东西

derived1。cxx:20:对' Base::helper1(unsigned char)的未定义引用其中helper1是一个在Base

中确实存在的(在我的代码中)受保护的方法

或者

derived1。Cxx:28:未定义引用' derived1::helper2(unsigned char, unsigned char)其中helper2是派生的私有方法,它确实存在于我的代码中。这很奇怪,因为derived1编译得很好。您认为在编译过程中,它会因为查找helper2方法而抛出错误吗?

或者如果我把include弄乱了,我会得到

错误:无法将' SenseType'从' SenseType'转换为' Response '

我知道是我的include搞砸了,或者我只是完全没有能力做一个工厂模式。网上所有的例子都让它看起来像我做对了,他们只是从来没有包括在内。我猜是

我对我所有的头文件都有保护。此外,如果有帮助的话,所有的链接器错误都在派生类中。

所以我是在为那些犯同样愚蠢错误的人回答我自己的问题。

对于底部的错误信息

derived1.cxx:20: undefined reference to `Base::helper1(unsigned char)

我在cxx文件中没有void Base::helper1(),我有void helper1()

我仍然不明白为什么它没有在编译时捕获它?为什么直到联动时才显示错误?

对于您在自己的回答中提出的问题,我认为,因为您没有使用Base::在函数中进行作用域,因此它将其视为全局函数,因此直到它试图链接文件才抱怨。我以前遇到过这个问题,从那时起,我不得不养成习惯,总是在.cpp文件中包含的任何函数中进行作用域。

如果没有对您的情况有更大的了解,很难说,但我的猜测是,您的代码正在编译,因为它在每个编译单元(每个单独的cpp/cxx文件)中仍然有效。

c++允许你声明一些东西,但不定义它,并且它可以很好地编译。只要没有引用未定义的东西,编译甚至链接都不会出错。

然而,如果你试图引用一些没有定义的东西,你会得到链接器错误。

例子:(Test.h)

class Test
{
public:
    int methodA();
    int methodB();
};

现在在Test.cpp

    #include "Test.h"
    int Test::methodA() { return 42; }

在这种情况下,编译单元"Test.cpp"将编译得很好。然而,如果我们有一个Main.cpp,如下所示…

#include "Test.h"
void main()
{
    Test test;
    test.methodA(); // Works fine...
    // test.methodB() <-- Causes linker error if uncomented.    
}

所以你可以很容易地得到这样的情况:所有的文件都可以自己"编译",但在链接时遇到错误。

编辑以解决您的其他问题。如果有,它将是特定于编译器的。我不了解VisualStudio,但我相信GCC有这样的标志。参见强制GCC通知共享库中未定义的引用