在c++中实现工厂模式
Implementing Factory Pattern in C++
我基本上有标题问题。
#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通知共享库中未定义的引用
- 工厂方法模式使用继承而抽象工厂模式使用组合如何
- 使用宏替换工厂模式样式 API 中的"create()"函数
- 使用工厂模式实施单例
- 工厂模式与unique_ptr
- 具有多个继承的工厂模式
- 工厂模式和单例模式:未定义的引用
- 实现工厂模式时虚拟功能的多重定义
- dlopen、工厂模式和虚拟方法表
- 工厂模式和std::绑定方法
- C++带有模板的工厂模式
- 将命令模式,工厂模式和模板混合在一起..
- 双重调度和工厂模式
- 在工厂模式中传递值
- 抽象工厂模式客户端代码
- boost::系列化和工厂模式设计
- 使用可变参数模板的工厂模式
- 在多个库上拆分工厂(模式)
- 打破工厂模式中的循环依赖关系
- 在编译时分配内存的工厂模式,以及如何打印编译时信息
- 在C++中使用静态方法来实现工厂模式