Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何向前声明自定义构造函数?_C++ - Fatal编程技术网

C++ 如何向前声明自定义构造函数?

C++ 如何向前声明自定义构造函数?,c++,C++,注意:我发现了我的Xcode如何编译下面的代码的问题,它似乎与本文讨论的主题无关。当我有更多的细节,我会提供他们在这里 我建议投票将我的问题关闭为“太本地化”,因为它是XCube问题,与C++代码本身无关。非常感谢你的帮助,尽管我从答案中学到了很多 下面的问题(现在已回答并解决)是由于从Xcode目标中排除了一个文件而导致的,因此即使该文件有问题,也没有编译器错误 我有一个纯虚拟接口,希望定义它的工厂方法,它返回这个接口的一个子类。这很好: struct MyVirt{ ...all virt

注意:我发现了我的Xcode如何编译下面的代码的问题,它似乎与本文讨论的主题无关。当我有更多的细节,我会提供他们在这里

我建议投票将我的问题关闭为“太本地化”,因为它是XCube问题,与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);
}
问题是
转发声明不再足够。它需要查看类定义或其标题。这意味着我可以将factory方法移动到定义了
SubVirt
的文件中,或者我必须将该文件包含在上面的文件中,这会创建循环依赖关系


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

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

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

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

你能做的是:

  • 在头文件中:向前声明
    SubVirt
    CreateClass
    函数
  • cpp文件:包括
    MyVirt.h
    和定义
    CreateClass
    函数

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

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

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

你能做的是:

  • 在头文件中:向前声明
    SubVirt
    CreateClass
    函数
  • cpp文件:包括
    MyVirt.h
    和定义
    CreateClass
    函数

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

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();
Factory.cpp:

#include "SubVirt.h"
MyVirt *CreateClass() { return new SubVirt() }

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

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();
Factory.cpp:

#include "SubVirt.h"
MyVirt *CreateClass() { return new SubVirt() }

这可以通过分离声明和实现来实现

这里的关键是将定义/实现置于包含之上。假设要将类A和B分开,请创建两个文件,如下所示:

A.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;
}

#include

这可以通过分离声明和实现来实现

这里的关键是将定义/实现置于包含之上。假设要将类A和B分开,请创建两个文件,如下所示:

A.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;
}

#include

我很难理解:
新SubVirt
也需要查看
SubVirt
的定义,对吗?因此,返回指针时必须包含头,编译器需要知道具体的指针大小,所以前向声明是不够的。@SebbyJohanns:
new
运算符需要查看类的定义,不能只提供前向声明。如果使用了不完整的类型,它将不会编译。所以这意味着你必须在某个地方包含一个标题。@SebbyJohanns你认为
new
有什么魔力可以用一个正向声明推断出你的对象的大小?或者它应该采取一个potshot,并希望分配的内存至少与您的对象一样大?你的说法是荒谬的。@SebbyJohanns:我不确定你指的是什么答案,但
new
需要查看类的定义才能确定要分配多少内存。它怎么能仅仅从你们班的名字就猜出来呢?您的类是否包含3、4或145个成员变量?什么类型的?因此,要么你没有向我们展示真正的代码,要么你根本没有编译任何代码。我很难理解:
newsubvirt
还需要查看
SubVirt
的定义,对吗?因此,返回指针时必须包含头,编译器需要知道具体的指针大小,所以前向声明是不够的。@SebbyJohanns:
new
运算符需要查看类的定义,不能只提供前向声明。如果使用了不完整的类型,它将不会编译。所以这意味着你必须在某个地方包含一个标题。@SebbyJohanns你认为
new
有什么魔力可以用一个正向声明推断出你的对象的大小?或者它应该采取一个potshot,并希望分配的内存至少与您的对象一样大?你的说法是荒谬的。@SebbyJohanns:我不确定你指的是什么答案,但
new
需要查看类的定义才能确定要分配多少内存。它怎么能仅仅从你们班的名字就猜出来呢?您的类是否包含3、4或145个成员变量?什么类型的?因此,要么你没有向我们展示真正的代码,要么你根本没有编译任何代码。”当返回指针时,编译器需要知道具体的指针“指针大小总是相同的。当您声明返回结构指针的内容时,向前声明就足够了。当你实现它时,你需要完整的声明。@SebbyJohanns,这不合理