#include <iostream>
using namespace std;
class Street;
class CrossStreet
{
private:
char m_chName;
Street* m_acLoS;
int m_nNoS;
static int m_nCSid;
public:
CrossStreet()
{
Init();
m_chName = m_nCSid;
}
CrossStreet(char chName)
{
Init();
m_chName = chName;
}
/** Problem is here **/
void AddStreet(Street* const cStreet)
{
m_acLoS[++m_nNoS] = cStreet;
}
~CrossStreet()
{
delete[] m_acList;
}
void Init()
{
m_nNoS = 0;
m_acLoS = 0;
m_nCSid++;
}
friend class Street;
};
class Street
{
private:
int m_nDistance;
public:
Street(CrossStreet& cHead, CrossStreet& cTail, int nDistance)
{
CreateStreet(cHead,cTail,nDistance);
}
void CreateStreet(CrossStreet& cHead, CrossStreet& cTail, int nDistance)
{
m_nDistance = nDistance;
cHead.AddStreet(Street* const THIS);
cTail.AddStreet(Street* const THIS);
}
};当我编译上面的代码时,抛出了这个错误:
-->>invalid use of incomplete 'struct Street'
-->>forward declaration of 'struct Street'在' CrossStreet‘的对象上调用了’CrossStreet‘对象的函数AddStreet,以便将'THIS street object’添加到CrossStreet对象的成员变量中。所以我想我可以在这种情况下使用这个指针,但它不能编译。
发布于 2012-03-16 02:08:57
没有像THIS指针这样的东西。不过,这里有一个this指针。所以你在CreateStreet中的代码是无效的(不仅如此)。正确的语法应该是:
cHead.AddStreet(this); // no cast neededAddStreet中的问题是您已经将m_acLoS定义为指向街道的指针。所以m_acLoS[x]的类型是Street,而不是Street*。但是您不能在那里使用Street对象,因为那时您还没有一个完整的Street定义。在CrossStreet中只能使用指向街道的指针。(此外,您缺少用于m_acLoS的存储分配,所以即使您可以在那里使用该类型,如果分配是合法的,它仍然是一个错误)。
根据您要查找的内容,std::vector<Street*>、std::list<Street*>或其他容器可能是您要查找的对象,而不是不正确的成员数组。(但请注意,您要负责管理这些指针的生命周期。)
发布于 2012-03-16 02:06:07
与this指针无关,它与转发声明有关。您是说Street在您的转发声明中是一个class,但是它没有指定它的定义,所以在定义它之前尝试使用它的定义是错误的。
也就是说,使用转发声明:
class Street;你可以这样说:
Street* pS
Street& rS因为这些不需要街道的定义。但是,一旦以需要定义的方式使用它(赋值Street对象),您就需要完整的定义。
// m_acLoS是一条街*,所以m_acLoS...是指一条街。m_acLoS++m_nNoS = cStreet;
看起来您确实希望数组是指向Street的指针数组,而不是指向Street的数组(实际上,向量可能更好)。
但是,一般而言,由于您的CrossStreet依赖于街道,街道依赖于CrossStreet,因此您应该将每个类的声明放在它们自己的头文件中,并将实现放在它们自己的.cpp文件中,这样带有源代码的.cpp文件就可以在使用它们的任何代码之前#include这两个完整的声明。
发布于 2012-03-16 02:37:01
已经有几个人告诉你这个问题了。这更多地关注于解决方案。我通常倾向于将类实现与类定义分离。我会重新组织代码,如下所示:
#include <iostream>
using namespace std;
class Street;
class CrossStreet {
char m_chName;
Street* m_acLoS;
int m_nNoS;
static int m_nCSid;
void Init();
public:
CrossStreet();
CrossStreet(char chName);
void AddStreet(Street* const cStreet);
~CrossStreet();
friend class Street;
};
class Street {
int m_nDistance;
public:
Street(CrossStreet& cHead, CrossStreet& cTail, int nDistance);
void CreateStreet(CrossStreet& cHead, CrossStreet& cTail, int nDistance);
};
CrossStreet::CrossStreet() {
Init();
m_chName = m_nCSid;
}
CrossStreet::CrossStreet(char chName) {
Init();
m_chName = chName;
}
void CrossStreet::AddStreet(Street* const cStreet) {
m_acLoS[++m_nNoS] = cStreet;
}
CrossStreet::~CrossStreet() {
delete[] m_acList;
}
CrossStreet::void Init() {
m_nNoS = 0;
m_acLoS = 0;
m_nCSid++;
}
Street::Street(CrossStreet& cHead, CrossStreet& cTail, int nDistance) {
CreateStreet(cHead,cTail,nDistance);
}
void Street::CreateStreet(CrossStreet& cHead, CrossStreet& cTail, int nDistance) {
m_nDistance = nDistance;
cHead.AddStreet(this);
cTail.AddStreet(this);
}所以,这里的基本思想是一个类声明,然后是类定义,然后是成员函数的实现。还要注意的是,我已经将CrossStreet::Init设置为私有的,因为它显然只应该由CrossStreet成员使用。
最后,看在上帝的份上,请为您的变量选择一些像样的名称。您使用过的唯一一个不太有意义和可读性的名称是m_nDistance。像m_chName和m_acLos这样的东西真的非常糟糕。这些名字看起来很像我在抨击匈牙利符号的坏处和从中得到的丑陋、难以阅读的混乱时发明的名字。
https://stackoverflow.com/questions/9725426
复制相似问题