如何转发声明自定义构造函数?

时间:2013-02-01 23:30:38

标签: c++

注意:我发现了我的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的文件,或者我必须在上面的文件中包含该文件,这会创建循环依赖。

有没有办法转发声明自定义构造函数?这会使事情变得更加简单。

3 个答案:

答案 0 :(得分:3)

您的CreateClass函数看起来很奇怪,您在函数定义中错过了()。应该是这样的:

MyVirt* CreateClass()
{
    return new SubVirt(arg 1, etc);
}

当返回指针时,编译器需要知道具体的类型和构造函数,因此前向声明是不够的。

你能做的是:

    头文件中的
  • :转发声明SubVirtCreateClass函数
  • cpp文件:包含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文件中。这只是基本配方,它显示了即使对于模板化的类和函数,如何解决循环依赖。

http://codepad.org/IsBzQANX