在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)
似乎这可能会使事情变得更加混乱.这会对前向声明产生问题,如果是这样,有一个简单的解决方法吗?
可能重复:
何时使用前向声明?
在特定类之上指定其他类名有什么用?
class A;
class B;
class C
{
...
...
};
Run Code Online (Sandbox Code Playgroud) 我正在尝试尽可能多地使用前向声明来最小化编译时间.我注意到当我转发声明一个使用类似std :: vector的类作为成员对象的类时(这里的例子):
class myTypeA
class A
{
A(){};
~A(){};
std::vector<myTypeA > getTypeA();
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
microsoft visual studio 9.0\vc\include\vector(1112) : error C2036: 'myTypeA *' : unknown size
1> c:\program files\microsoft visual studio 9.0\vc\include\vector(1102) : while compiling class template member function 'bool std::vector<_Ty>::_Buy(unsigned int)'
1> with
1> [
1> _Ty=myTypeA
1> ]
1> d:\cpp\A.h(15) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1> with
1> [
1> _Ty=myTypeA
1> ]
Run Code Online (Sandbox Code Playgroud)
当我使用#include"myTypeA.h"时,这工作正常,为什么?
我是C++的新手,面临循环依赖问题.有人可以帮我解决这个问题吗?
我有两节课:
class Vertex {
string name;
int distance;
//Vertex path;
int weight;
bool known;
list<Edge> edgeList;
list<Vertex> adjVertexList;
public:
Vertex();
Vertex(string nm);
virtual ~Vertex();
};
class Edge {
Vertex target;
int weight;
public:
Edge();
Edge(Vertex v, int w);
virtual ~Edge();
Vertex getTarget();
void setTarget(Vertex target);
int getWeight();
void setWeight(int weight);
};
Run Code Online (Sandbox Code Playgroud)
上面的代码给出了以下错误:
我该如何解决这个问题?
我有一个类ID3和一个类Tree.类树的对象在ID3中使用,并显示未声明树的错误.
代码看起来像
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <math.h>
#include <vector>
using namespace std;
class ID3 {
public:
string v[];
int x;
public:
double Hi(Tree data)
{
int y=x-1;
}
};
class Tree{
Tree();
}
Run Code Online (Sandbox Code Playgroud) 我试图转发声明一个模板类,然后使用该类在其他类中声明成员数据。代码如下:
\n\nusing namespace std;\n\ntemplate<class T>\nclass B;\n\nclass A{\n B<T> b;\n};\n\ntemplate<class T>\nclass B{\n T x;\n};\n\nint main(){\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我得到编译错误:
\n\nerror: \xe2\x80\x98T\xe2\x80\x99 was not declared in this scope\n B<T> b;\nRun Code Online (Sandbox Code Playgroud)\n\n有人可以让我知道我做错了什么以及如何实现我的目标吗?(我注意到关于模板类的帖子,但没有一个回答我的问题。)
\n\n预先非常感谢!
\n我遇到以下问题,有人有好主意吗?
\n\nclass Vector_2d;\n\nnamespace Utils {\n\nclass Align_vector : public Vector_2d {\nprotected:\n bool check_range(int x, int y);\n\npublic:\n enum alignment {left, right, up, down};\n\n Align_vector(Alignment alignment);\n void set_alignment(Alignment alignment);\n Alignment get_alignment();\n\n};\n\n}\nRun Code Online (Sandbox Code Playgroud)\n\n错误是:
\n\n\n\n\n错误:无效使用不完整类型 \xe2\x80\x98class Vector_2d\xe2\x80\x99
\n
但怎么会出现错误呢?
\n我使用以下简单文件重现错误.
它说:
字段有不完整类型'Foo'
bar.h:
class Foo;
class Bar{
private:
int x_;
Foo foo_; // error: incomplete type
public:
void setx(int x) {x_ = x;};
void increment(int);
};
class Foo{
public:
void run(int y,Bar& bar) {bar.setx(y);};
};
void Bar::increment(int i){foo_.run(i,*this);}
Run Code Online (Sandbox Code Playgroud)
成员foo_不能是引用或指针.原因是在我的实际代码中,我无法在Bar的初始化列表中初始化Foo.
我做了这样的事情:
struct Vertex {
list<Edge*> edges;
};
struct Edge {
Vertex* v1;
Vertex* v2;
};
Run Code Online (Sandbox Code Playgroud)
和编译器错误:
'Edge'未在此范围内声明
如何在不将这两个标题放入单独的标题"vertex.h"和"edge.h"的情况下解决这个问题?