簡體   English   中英

如何轉發聲明一個類的成員函數在另一個類中使用?

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

我已經制作了兩個相同的類X和Y,並且指向了彼此。 請參閱下面的代碼Xh,Yh與所有X和Y的互換相同。 但是,此代碼在我的方法Connect中出錯(錯誤C2027:使用未定義類型'Y')。 在Xh中,我已經向前聲明了類Y,但它不知道Y有一個名為SetXPointer的方法。 因此我還需要轉發聲明這個方法,對嗎?

如果我嘗試這樣做(添加行Y :: SetXPointer(X * pX_in);在行類Y;)下,我得到編譯器錯誤C2761:'void Y :: SetXPointer(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;
};

不要在類體中包含方法體。 編寫這兩個類,在兩個類完成后,編寫方法實現:

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聲明的方法都將以相同的方式內聯,性能也將是相同的。

唯一的缺點是你不能以合理的方式將這兩個類分成兩個標題。

如果您的類在其方法中都需要完整類型,那么執行此操作的唯一方法是將實現與實現文件分開。

如果您打算在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;

由於模板方法僅在使用時進行實例化,因此可以避免上述問題,因為在實例化時,兩種類型都是已知的。 如果稍后您在XY之間存在差異,則可以使用繼承而不是typedef

您可以將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