17

我制作了两个相同的类 X 和 Y,并带有一个指向彼此的指针。Xh,Yh 与所有交换的 X 和 Y 相同,请参见下面的代码。但是,此代码在我的方法 Connect 中出现错误(错误 C2027:使用未定义的类型“Y”)。在 Xh 中,我已经前向声明了类 Y,但它不知道 Y 有一个名为 SetXPointer 的方法。因此我也需要转发声明这个方法,对吗?

如果我尝试这样做(在行类 Y; 下添加行 Y::SetXPointer(X* pX_in);),我会收到编译器错误 C2761: 'void Y::SetXPointer(X *)' : member function redeclaration不允许。有没有办法在 X 类中使用 Y 类的公共方法?

// X.h

#pragma once

#include "Y.h"

// Forward declaration
class Y;

class X
{
public:
    X(void) : data(24) {};
    ~X(void) {};
    int GetData() { return data; }
    void SetYPointer(Y* pY_in) { pY = pY_in; }
    Y* GetYPointer() { return pY; }
    void Connect(Y* Y_in) { pY = Y_in; Y_in->SetXPointer(this); }
private:
    int data;
    Y *pY;
};
4

4 回答 4

21

不要在类主体中包含方法主体。编写两个类,两个类都完成后,编写方法实现:

class Y;
class X {
  …
  void Connect(Y* Y_in);
  …
};
class Y {
  …
  void Connect(X* X_in);
  …
};
inline void X::Connect(Y* Y_in) {
  pY = Y_in;
  Y_in->SetXPointer(this);
}
inline void Y::Connect(X* X_in) {
  pX = X_in;
  X_in->SetXPointer(this);
}

这样,在实现方法时,就可以获得有关类对象如何在内存中布局的完整信息Connect。并且由于类主体中的方法和声明的方法inline都将以相同的方式内联,因此性能也将相同。

唯一的缺点是您将无法以合理的方式将这两个类拆分为两个标题。

于 2012-07-05T12:25:36.673 回答
4

如果您的两个类在其方法中都需要完整类型,那么唯一的方法是将实现分离到一个实现文件中。

于 2012-07-05T12:19:18.493 回答
3

您可以将 B 类放入 A 类

using namespace std;

class A
{
        public:
        void run()
        {
                B b("hi");
                b.run(this);
        }

        void print(string &msg) { cout << msg << endl; }

        private:
        class B
        {
                public:
                B(string m) : msg(m) {}
                void run(A *a) { a->print(msg); }

                private:
                string msg;
        };
};

int main()
{
        A a;
        a.run();
        return 0;
}
于 2014-01-20T18:46:14.900 回答
2

如果您打算在 X 和 Y 之间共享大部分实现,您可能希望使用模板来实现。一个例子如下:

template<bool isX> class XY
{
public:
  typedef XY<!isX> YX; // This is the opposite type to the current one.
  XY(void) : data(24) {};
  ~XY(void) {};
  int GetData() { return data; }
  void SetPointer(YX* pYX_in) { pYX = pYX_in; }
  YX* GetPointer() { return pYX; }
  void Connect(YX* YX_in) { pYX = YX_in; YX_in->SetPointer(this); }
private:
  int data;
  YX *pYX;
};

typedef XY<true> X;
typedef XY<false> Y;

由于模板方法仅在使用时才被实例化,因此可以避免上述问题,因为当它们被实例化时,这两种类型都是已知的。X如果您以后在和之间存在差异Y,您可能会使用继承而不是typedef.

于 2012-07-05T12:31:59.510 回答