注意:我发现了我的Xcode如何编译以下内容的问题,它似乎与此处讨论的主题无关。当我有更多细节时,我会在这里提供。
我建议投票将我的问题关闭为“过于本地化”,因为它是一个Xcode问题,与c ++代码本身无关。非常感谢帮助,就像我从答案中学到的一样。
以下问题(现已回答并解决)是由于Xcode目标中文件的混乱排除造成的,因此即使文件出现问题也没有编译错误。
我有一个纯虚拟接口,想要定义它的工厂方法,它返回这个接口的子类。这很好用:
struct MyVirt{
...all virtual stuff
};
class SubVirt; //forward declaration allows factory:
MyVirt*CreateClass(){
return new SubVirt;
}
更新:有些评论说前向声明不足以实现上述目标,但这不正确。如果没有SubVirt
类的完整定义,您可以完成上述任务。
现在,我想要做的是拥有一个带参数的自定义构造函数。就这样:
MyVirt*CreateClass(){
return new SubVirt(arg 1, etc);
}
问题在于class
前向声明已不再足够。它需要查看类定义或其标题。这意味着我可以将工厂方法移动到定义SubVirt
的文件,或者我必须在上面的文件中包含该文件,这会创建循环依赖。
有没有办法转发声明自定义构造函数?这会使事情变得更加简单。
答案 0 :(得分:3)
您的CreateClass函数看起来很奇怪,您在函数定义中错过了()
。应该是这样的:
MyVirt* CreateClass()
{
return new SubVirt(arg 1, etc);
}
当返回指针时,编译器需要知道具体的类型和构造函数,因此前向声明是不够的。
你能做的是:
SubVirt
和CreateClass
函数MyVirt.h
并定义CreateClass
功能答案 1 :(得分:3)
与所有人一样,将声明与实施分开。
MyVirt.h:
struct MyVirt{
...all virtual stuff
};
MyVirt.cpp:
#include "MyVirt.h"
Implementation of MyVirt
SubVirt.h:
#include "MyVirt.h"
struct SubVirt : MyVirt {
...all SubVirt stuff
};
SubVirt.cpp:
#include "SubVirt.h"
Implementation of SubVirt
Factory.h:
struct MyVirt;
MyVirt *CreateClass();
Factory.cpp:
#include "SubVirt.h"
MyVirt *CreateClass() { return new SubVirt() }
答案 2 :(得分:0)
这可以通过分离声明和实现来实现。
这里的关键是将定义/实现置于之上。假设您要分离类A和B,请创建两个文件,如下所示:
A.hpp
#ifndef A_HPP
#define A_HPP
struct B; // fwd. decl.
struct A {
int v;
A(int v) {
this->v = v;
}
B* createB();
};
#include "B.hpp"
A* B::createA() {
return new A(v);
}
#endif A_HPP
B.hpp
#ifndef B_HPP
#define B_HPP
struct A; // fwd. decl.
struct B {
int v;
B(int v) {
this->v = v;
}
A* createA();
};
#include "A.hpp"
B* A::createB() {
return new B(v);
}
#endif // B_HPP
main.hpp
#include <A.hpp>
#include <B.hpp>
#include <iostream>
int main(int argc, char *argv[]) {
A a(42);
std::cout << a.createB()->createA()->v << std::endl;
return 0;
}
您当然可以自由地将实现移到cpp
文件中。这只是基本配方,它显示了即使对于模板化的类和函数,如何解决循环依赖。