如何声明具有在声明下方定义的类型的参数的函数?

Posted

技术标签:

【中文标题】如何声明具有在声明下方定义的类型的参数的函数?【英文标题】:How do I declare a function that has a parameter of a type that's defined below the declaration? 【发布时间】:2020-05-20 20:15:14 【问题描述】:

我正在尝试实现自定义 Vector2(2D 向量)和 Matrix2(2x2 矩阵)类。我想定义一个对向量执行仿射变换的函数,就好像它是二维空间中的一个点。为此,我需要传递变换矩阵、可选的变换原点和可选的平移。

我希望这个函数成为我的 Vector2 类的成员。但是,我对 Matrix2 的定义位于定义此函数的 Vector2 定义的下方。因此,当我尝试编译代码时出现编译错误:

C2061 语法错误:标识符“Matrix2”

我的 Matrix2 定义包括一个将矩阵乘以向量的函数,所以我需要在 Vector2 之后定义 Matrix2。

这里是代码,省略了不相关的成员:

#pragma once

namespace AWUtils

    struct Vector2
    
        double x;
        double y;

        // default constructor, produces the zero vector
        Vector2()
        
            zero();
        

        // copy constructor, copies the given vector
        Vector2(const Vector2* v)
        
            x = v->x;
            y = v->y;
        

        // turns this vector into the zero vector
        void zero()
        
            x = 0;
            y = 0;
        

        // returns a new vector equal to this vector plus the given vector
        Vector2 add(Vector2 v)
        
            return Vector2(x + v.x, y + v.y);
        

        Vector2 operator + (Vector2 v)
        
            return add(v);
        

        Vector2 operator - (Vector2 v)
        
            return add(v * -1);
        

        // affine transformation
        Vector2 transform(Matrix2 matrix, Vector2 origin = Vector2(), Vector2 translation = Vector2())
        
            Vector2 me(this);
            return (matrix * (me + translation - origin)) + origin;
        
    ;

    struct Matrix2
    
        double a;
        double b;
        double c;
        double d;

        // vector multiplication
        Vector2 multiply(Vector2 v)
        
            return Vector2(a * v.x + b * v.y, c * v.x + d * v.y);
        

        Vector2 operator * (Vector2 v)
        
            return multiply(v);
        
    ;

我必须在别处定义这个函数吗?我考虑过在 Matrix2 下定义它,但我更希望它是一个成员函数。任何帮助(包括代码批评,我已经做了不到两周的 C++)将不胜感激。

【问题讨论】:

看起来罪魁祸首是Vector2::transform。我会将其移出Vector2 作为独立功能。您也许可以将该功能楔入Matrix2,但我不建议这样做。 【参考方案1】:

当您有两个相互依赖的类时,您将需要转发声明其中一个类并移动成员函数的实现,以便类定义在函数实现之前完成。

namespace AWUtils

    // Forward declaration.
    struct Matrix2;

    struct Vector2
    
        ... 

        // Declare 
        // affine transformation
        Vector2 transform(Matrix2 matrix, Vector2 origin = Vector2(), Vector2 translation = Vector2());
    ;

    struct Matrix2
    
       ...
    ;

    // Define 
    // affine transformation
    Vector2 Vector2::transform(Matrix2 matrix, Vector2 origin, Vector2 translation)
    
        Vector2 me(this);
        return (matrix * (me + translation - origin)) + origin;
    

【讨论】:

【参考方案2】:

定义要和声明分开,struct Matrix2必须在Vector2之前声明。

struct Matrix2;

Vector2

Vector2 transform(const Matrix2& matrix, Vector2 origin = Vector2(), Vector2 translation = Vector2());

Vector2Matrix2 之后

Vector2 Vectors::transform(const Matrix2& matrix, Vector2 origin, Vector2 translation)

    Vector2 me(this);
    return (matrix * (me + translation - origin)) + origin;

另外方法应该是 const

Vector2 multiply(Vector2 v) const

    return Vector2(a * v.x + b * v.y, c * v.x + d * v.y);


Vector2 operator * (Vector2 v) const

     return multiply(v);

【讨论】:

以上是关于如何声明具有在声明下方定义的类型的参数的函数?的主要内容,如果未能解决你的问题,请参考以下文章

C语言函数定义和说明的格式

python3在函数声明里如何设置参数的类型 dict

当一个函数无返回值时,函数的类型应定义为啥

为函数定义接口,我无权访问该声明

163-委托的定义和声明

C函数语法,在参数列表之后声明的参数类型