简体   繁体   English

如何转发声明一个类的成员函数在另一个类中使用?

[英]How to forward declare a member function of a class to use in another class?

I have made two identical classes X and Y, with a pointer to each other. 我已经制作了两个相同的类X和Y,并且指向了彼此。 See the code below for Xh, Yh is identical with all X's and Y's interchanged. 请参阅下面的代码Xh,Yh与所有X和Y的互换相同。 This code gives however an error in my method Connect (error C2027: use of undefined type 'Y'). 但是,此代码在我的方法Connect中出错(错误C2027:使用未定义类型'Y')。 In Xh, I have forward declared the class Y, but it doesn't know that Y has a method named SetXPointer. 在Xh中,我已经向前声明了类Y,但它不知道Y有一个名为SetXPointer的方法。 Therefore I also need to forward declare this method, correct? 因此我还需要转发声明这个方法,对吗?

If I try to do this (adding the line Y::SetXPointer(X* pX_in); under the line class Y;), I get a compiler error C2761: 'void Y::SetXPointer(X *)' : member function redeclaration not allowed. 如果我尝试这样做(添加行Y :: SetXPointer(X * pX_in);在行类Y;)下,我得到编译器错误C2761:'void Y :: SetXPointer(X *)':成员函数重新声明不允许。 Is there a way to use a public method of class Y in class X? 有没有办法在类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;
};

Don't include the method body in the class body. 不要在类体中包含方法体。 Write both classes, and after both classes are complete, write the method implementations: 编写这两个类,在两个类完成后,编写方法实现:

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);
}

That way, full information about how the objects of the class will be layed out in memory is available by the time the Connect method is implemented. 这样,在实现Connect方法时,可以获得有关如何将类对象放置在内存中的完整信息。 And as a method in the class body and a method declared inline will both be inlined the same way, performance will be the same as well. 并且作为类体中的方法和inline声明的方法都将以相同的方式内联,性能也将是相同的。

The only downside is that you won't be able to split these two classes over two headers in a reasonable way. 唯一的缺点是你不能以合理的方式将这两个类分成两个标题。

如果您的类在其方法中都需要完整类型,那么执行此操作的唯一方法是将实现与实现文件分开。

If you intend to share large parts of the implementation between X and Y, you might want to do that using a template. 如果您打算在X和Y之间共享大部分实现,您可能希望使用模板来实现。 One example is the following: 一个例子如下:

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;

As template methods are only instantiated when used, you avoid the problem outlined above, as by the time they are instantiated, both types are known. 由于模板方法仅在使用时进行实例化,因此可以避免上述问题,因为在实例化时,两种类型都是已知的。 If you later on have differences between X and Y , you might use inheritance instead of typedef . 如果稍后您在XY之间存在差异,则可以使用继承而不是typedef

You can place class B into class A 您可以将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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM