首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我可以在friend类中使用这个指针吗?

我可以在friend类中使用这个指针吗?
EN

Stack Overflow用户
提问于 2012-03-16 01:56:36
回答 3查看 1.2K关注 0票数 1
代码语言:javascript
复制
#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);

              }

};

当我编译上面的代码时,抛出了这个错误:

代码语言:javascript
复制
-->>invalid use of incomplete 'struct Street'
-->>forward declaration of 'struct Street'

在' CrossStreet‘的对象上调用了’CrossStreet‘对象的函数AddStreet,以便将'THIS street object’添加到CrossStreet对象的成员变量中。所以我想我可以在这种情况下使用这个指针,但它不能编译。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-16 02:08:57

没有像THIS指针这样的东西。不过,这里有一个this指针。所以你在CreateStreet中的代码是无效的(不仅如此)。正确的语法应该是:

代码语言:javascript
复制
cHead.AddStreet(this); // no cast needed

AddStreet中的问题是您已经将m_acLoS定义为指向街道的指针。所以m_acLoS[x]的类型是Street,而不是Street*。但是您不能在那里使用Street对象,因为那时您还没有一个完整的Street定义。在CrossStreet中只能使用指向街道的指针。(此外,您缺少用于m_acLoS的存储分配,所以即使您可以在那里使用该类型,如果分配是合法的,它仍然是一个错误)。

根据您要查找的内容,std::vector<Street*>std::list<Street*>或其他容器可能是您要查找的对象,而不是不正确的成员数组。(但请注意,您要负责管理这些指针的生命周期。)

票数 3
EN

Stack Overflow用户

发布于 2012-03-16 02:06:07

this指针无关,它与转发声明有关。您是说Street在您的转发声明中是一个class,但是它没有指定它的定义,所以在定义它之前尝试使用它的定义是错误的。

也就是说,使用转发声明:

代码语言:javascript
复制
class Street;

你可以这样说:

代码语言:javascript
复制
Street* pS
Street& rS

因为这些不需要街道的定义。但是,一旦以需要定义的方式使用它(赋值Street对象),您就需要完整的定义。

// m_acLoS是一条街*,所以m_acLoS...是指一条街。m_acLoS++m_nNoS = cStreet;

看起来您确实希望数组是指向Street的指针数组,而不是指向Street的数组(实际上,向量可能更好)。

但是,一般而言,由于您的CrossStreet依赖于街道,街道依赖于CrossStreet,因此您应该将每个类的声明放在它们自己的头文件中,并将实现放在它们自己的.cpp文件中,这样带有源代码的.cpp文件就可以在使用它们的任何代码之前#include这两个完整的声明。

票数 3
EN

Stack Overflow用户

发布于 2012-03-16 02:37:01

已经有几个人告诉你这个问题了。这更多地关注于解决方案。我通常倾向于将类实现与类定义分离。我会重新组织代码,如下所示:

代码语言:javascript
复制
#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_chNamem_acLos这样的东西真的非常糟糕。这些名字看起来很像我在抨击匈牙利符号的坏处和从中得到的丑陋、难以阅读的混乱时发明的名字。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9725426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档