簡體   English   中英

我有兩個類需要在同一個 cpp 文件中相互引用,但第一個類無法識別第二個類類型的對象

[英]I have two classes that need to reference each other in the same cpp file, but the first one won't recognize objects of the second class type

編譯器給我:“變量的類型為rotation2d不完整”

class translation2d
{
    public:
       double x;
       double y;

        translation2d()
        {
            x=0;
            y=0;
        }
    translation2d rotateBy(rotation2d rotation) //issue here
    {
        translation2d copy=*this;
        copy=translation2d(x*rotation.cosM()-y*rotation.sinM(), x*rotation.sinM() + y*rotation.cosM());
        return copy;
    }
};
double kEpsilon = 0.000000009;

class translation2d;
class rotation2d
{

    public:
       double cosAngle;
       double sinAngle;

    public:
        rotation2d() 
        {
            cosAngle=1;
            sinAngle=0;
        }

        rotation2d(translation2d& direction, bool norm)
        {
            cosAngle=direction.x;
            sinAngle=direction.y;
            if(norm)
                normalize();
        }

    double cosM()
    {
        return cosAngle;
    }
    double sinM()
    {
        return sinAngle;
    }
    double tanM()
    {
        if(abs(cosAngle)<kEpsilon)
        {
            if(sinAngle>=0.0)
                return std::numeric_limits<double>::infinity();
            else
                return -1*std::numeric_limits<double>::infinity();
        }
        return sinAngle/cosAngle;
    }
}

為了解決 C++ 中的循環依賴,發明了前向聲明

不知何故,OP 嘗試過,但方式錯誤。

因此,如果

  • class translation2d需要class rotation2d

  • class rotation2d需要class translation2d

第二個必須在第一個之前向前聲明。

struct rotation2d; // forward declaration -> incomplete type

struct translation2d {
  void doSomethingWith(rotation2d rot);
};

struct rotation2d {
  void doSomethingWith(translation2d trans);
};

Compiler Explorer 上的演示

前向聲明使類型不完整 不完全類型在可以用它們做什么方面受到限制。

不完整類型的大小和內容均未知。 因此,編譯器拒絕所有需要這樣做的內容,例如

  • 存儲分配(即創建一個變量或它的成員變量)
  • 訪問內容(即讀/寫成員變量或調用成員函數)。

允許使用不完整的類型

  • 指針和引用(具有任何限定)
  • 函數聲明的參數。

我必須承認,我不知道后者,但發現:
SO:不完整的類型作為函數參數和返回值
為了我的啟蒙。

請注意,函數聲明的參數可能不完整,但函數定義的參數不完整。 因此,修復的第二部分是在函數中需要不完整的類型時使函數內聯。

struct rotation2d; // forward declaration -> incomplete type

struct translation2d {
  void doSomethingWith(rotation2d rot);
};

struct rotation2d {
  void doSomethingWith(translation2d trans)
  {
    trans; // will be processed somehow
  }
};

// now both types are complete

void translation2d::doSomethingWith(rotation2d rot)
{
  rot; // will be processed somehow
}

Compiler Explorer 上的演示


OP修復完成的示例代碼:

#include <iostream>
#include <limits>
#include <cmath>

class rotation2d; // forward declaration

class translation2d
{
    public:
       double x;
       double y;

        translation2d()
        {
            x=0;
            y=0;
        }
        translation2d(double x, double y): x(x), y(y) { }

    translation2d rotateBy(rotation2d rotation); //issue here fixed
};
double kEpsilon = 0.000000009;

class rotation2d
{

    public:
       double cosAngle;
       double sinAngle;

    public:
        rotation2d() 
        {
            cosAngle=1;
            sinAngle=0;
        }

        rotation2d(const translation2d& direction, bool norm)
        {
            cosAngle=direction.x;
            sinAngle=direction.y;
            if(norm)
                normalize();
        }

    double cosM()
    {
        return cosAngle;
    }
    double sinM()
    {
        return sinAngle;
    }
    double tanM()
    {
        if(abs(cosAngle)<kEpsilon)
        {
            if(sinAngle>=0.0)
                return std::numeric_limits<double>::infinity();
            else
                return -1*std::numeric_limits<double>::infinity();
        }
        return sinAngle/cosAngle;
    }

    void normalize()
    {
        const double len = std::sqrt(cosAngle * cosAngle + sinAngle * sinAngle);
        cosAngle /= len; sinAngle /= len;
    }
};

// both types complete now -> circular dependency resolved

translation2d translation2d::rotateBy(rotation2d rotation)
{
    translation2d copy=*this;
    copy=translation2d(x*rotation.cosM()-y*rotation.sinM(), x*rotation.sinM() + y*rotation.cosM());
    return copy;
}

int main()
{
    translation2d t(1.0, 2.0);
    rotation2d r(translation2d(0.0, 1.0), false);
    translation2d tR = t.rotateBy(r);
    std::cout << "tR: (" << tR.x << ", " << tR.y << ")\n";
}

輸出:

tR: (-2, 1)

在coliru上進行現場演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM