1

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

有没有办法转发声明自定义构造函数?这将使一切变得简单得多。

4

3 回答 3

4

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

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

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

你可以做的是:

  • 在头文件中:前向声明SubVirtCreateClass函数
  • cpp 文件:包含MyVirt.h和定义CreateClass函数
于 2013-02-01T23:37:26.820 回答
3

像每个人一样,将声明与实现分开。

MyVirt.h:

struct MyVirt{
...all virtual stuff
};

MyVirt.cpp:

#include "MyVirt.h"
Implementation of MyVirt

子虚拟机.h:

#include "MyVirt.h"
struct SubVirt : MyVirt {
...all SubVirt stuff
};

SubVirt.cpp:

#include "SubVirt.h"
Implementation of SubVirt

工厂.h:

struct MyVirt;
MyVirt *CreateClass();

工厂.cpp:

#include "SubVirt.h"
MyVirt *CreateClass() { return new SubVirt() }
于 2013-02-01T23:38:07.657 回答
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

主文件

#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

于 2013-02-01T23:53:36.927 回答