我有一个大的头文件(~10000行),由我的控件中的脚本/程序自动生成.
为了避免在我的类的声明中包含此文件,我转发声明我需要的几种类型:
--myclass.h
namespace bl {
class TypeA;
class TypeB;
}
// Other stuff and myclass definition...
Run Code Online (Sandbox Code Playgroud)
现在它证明了TypeA并且TypeB不是类名,而是在自动生成的文件中定义为:
typedef SomeUnspecifiedClassName TypeA;
typedef AnotherUnspecifiedClassName TypeB;
Run Code Online (Sandbox Code Playgroud)
在哪里SomeUnspecifiedClassName我的意思是我不能转发声明这个类型名称,因为它可能会在各种情况下发生变化.
我怎样才能转发声明typedef?(不能使用c ++ 11)
我有以下文件结构,其中包含封装类型结构的定义,当我尝试访问结构的成员时,Member access into incomplete type出现错误。问题是什么?
foo_encoder.c :
#include "foo.h"
//...
struct FooEncoder {
int A;
int B;
foo_int32 C;
//...
}
Run Code Online (Sandbox Code Playgroud)
foo.h :
extern "C" {
typedef struct FooEncoder FooEncoder;
//...
}
Run Code Online (Sandbox Code Playgroud)
foo_interface.h :
typedef struct MyFooEncInst FooEncInst;
Run Code Online (Sandbox Code Playgroud)
foo_interface.cc :
#include "foo_interface.h"
#include "foo.h"
//...
struct MyFooEncInst {
FooEncoder* encoder;
};
//...
MyFoo_Encode(FooEncInst* inst,...) {
//...
if (d > inst->encoder->C) { // This is where I get the error
//...
}
Run Code Online (Sandbox Code Playgroud)
foo_int32 在另一个地方定义。
虚幻引擎生成以下功能:
void AFlyingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
//stuff...
}
Run Code Online (Sandbox Code Playgroud)
注意参数类型之前的"class"说明符.这是什么意思?
在C++中,我有一个双重包含问题:
文件stuffcollection.h
#pragma once
#ifndef STUFFCOLLECTION_H
#define STUFFCOLLECTION_H
#include "Stage.h"
class Stuffcollection {
public:
bool myfunc( Stage * stage );
};
#endif // STUFFCOLLECTION_H
Run Code Online (Sandbox Code Playgroud)
文件stage.h:
#pragma once
#ifndef STAGE_H
#define STAGE_H
#include "Stuffcollection.h"
class Stage {
// stuffcollection used in stage.cpp
};
#endif // STAGE_H
Run Code Online (Sandbox Code Playgroud)
编译器错误:
\Stuffcollection.h|(line were bool myfunc is declared)|error: 'Stage' has not been declared|
||=== Build finished: 1 errors, 0 warnings ===|
有人可以解释为什么会发生这种情况以及如何解决这个问题?我已经使用include guard和pragma一次预处理器指令,它只是不起作用.
(如果我#include "Stuffcollection.h"从stage.h中删除并注释掉在stage.cpp中使用它的相应行,那么我的其余代码就可以正常工作了.这真的只是在将Stuffcollection包含到舞台中时突然停止工作.)
PS:舞台只是一个例子,我几乎每隔一个文件都使用stuffcollection,每次我都遇到这个问题.
编辑:我按照建议,现在的问题是invalid use of incomplete type,即虽然给出的答案解决了循环依赖的问题,但他们没有解决我正在处理的问题.我的问题在 …
我发现这个问题什么时候使用前向声明?这是有用的,但它是描述性的而不是规定性的.
我的场景通常是我使用指向另一个类的指针作为类成员或函数参数,所以我在标题中需要的只是一个前向声明(另外,如果我切换到使用boost shared_ptr,它们将是与使用前向声明兼容?).目前我只是包括标题,但现在我想知道我是否应该使用前向声明.
所以我的问题是,如果我可以使用前瞻性声明,我应该吗?我希望这个问题不是主观的,但如果没有最佳实践答案,那么使用前瞻性声明的利弊是什么?
UPDATE
只是为了扩展shared_ptr问题(我现在没有使用它们,而是考虑切换).如果我要使用它们,我想我会在类中使用typedef的shared_ptr类型.例如:
class Customer
{
public:
typedef std::tr1::shared_ptr<Customer> SharedPointer;
Customer() {}
virtual ~Customer() {}
virtual std::string GetName() const;
};
Run Code Online (Sandbox Code Playgroud)
似乎这可能会使事情变得更加混乱.这会对前向声明产生问题,如果是这样,有一个简单的解决方法吗?
在VS2008上编译此代码时:
#include <vector>
using namespace std;
class Vertex {
public: double X;
double Y;
double Z;
int id; // place of vertex in original mesh vertex list
vector<Vertex*> neighbor; //adjacent vertices
vector<Triangle*> face; // adjacent triangles
float cost; // saved cost of collapsing edge
Vertex *collapse; //
};
class Triangle {
public:
Vertex * vertex[3];
};
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
1>.\Triangle.cpp(15) : error C2065: 'Triangle' : undeclared identifier
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?
所以在这个又一个古老的C++代码库中,我经常发现这种风格:
// ...
void FooBar::Eggs(int spam);
void FooBar::Eggs(int spam) {
// implementation here
// ...
}
Run Code Online (Sandbox Code Playgroud)
一般来说,我确实理解在C++中声明一个函数的重点是什么,但是我找不到任何理由来进行这种复制.有没有理由不消除它?
嗨,我试图转发声明cv :: Mat类,但我不能让它工作.它给消息字段'frame'具有不完整的类型.
OpenGlImpl.h
namespace cv {
class Mat;
}
class OpenGLImpl {
private:
cv::Mat frame;
};
Run Code Online (Sandbox Code Playgroud)
我该如何正确地转发声明呢?
我刚刚发现这段代码在 VS 2010 的头文件中(至少)是合法的
class AClass; //forward declaration of AClass (incomplete type);
class UseAClass
{
public:
AClass returnAClass(); //return a copy of incomplete type - AClass ???
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释我为什么要写这个吗?
我以为你只能为前向声明的类创建一个引用或指针成员.但是,我惊讶地发现这是有效的:
#include <vector>
struct Donkey;
struct Cage
{
std::vector<Donkey> donkeys;
};
struct Donkey
{
};
int main()
{
Cage c;
}
Run Code Online (Sandbox Code Playgroud)
怎么std::vector能用前向声明的类来定义?这是标准吗?