C++ 如何向前声明自定义构造函数?
注意:我发现了我的Xcode如何编译下面的代码的问题,它似乎与本文讨论的主题无关。当我有更多的细节,我会提供他们在这里 我建议投票将我的问题关闭为“太本地化”,因为它是XCube问题,与C++代码本身无关。非常感谢你的帮助,尽管我从答案中学到了很多 下面的问题(现在已回答并解决)是由于从Xcode目标中排除了一个文件而导致的,因此即使该文件有问题,也没有编译器错误C++ 如何向前声明自定义构造函数?,c++,C++,注意:我发现了我的Xcode如何编译下面的代码的问题,它似乎与本文讨论的主题无关。当我有更多的细节,我会提供他们在这里 我建议投票将我的问题关闭为“太本地化”,因为它是XCube问题,与C++代码本身无关。非常感谢你的帮助,尽管我从答案中学到了很多 下面的问题(现在已回答并解决)是由于从Xcode目标中排除了一个文件而导致的,因此即使该文件有问题,也没有编译器错误 我有一个纯虚拟接口,希望定义它的工厂方法,它返回这个接口的一个子类。这很好: struct MyVirt{ ...all virt
我有一个纯虚拟接口,希望定义它的工厂方法,它返回这个接口的一个子类。这很好:
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
()
。应该是这样的:
MyVirt* CreateClass()
{
return new SubVirt(arg 1, etc);
}
当返回指针时,编译器需要知道具体的类型和构造函数,所以前向声明是不够的 你能做的是:
- 在头文件中:向前声明
和SubVirt
函数CreateClass
- cpp文件:包括
和定义MyVirt.h
函数CreateClass
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,这不合理