微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

只处理一个文件时,有什么方法可以进行前向声明

如何解决只处理一个文件时,有什么方法可以进行前向声明

我有 2 个相互依赖的类,但我找不到让前向声明起作用的方法。我知道如何使用多个 cpp 和头文件来做到这一点,我只是想知道是否有办法在单个文件中做到这一点。

class cls2;

class cls1
{
public:
    int vi;
    cls1(int v = 30)
    {
        vi = v;
    }
    cls1(cls2 p)
    {
        vi = p.vi;
    }
};

class cls2
{
public:

    int vi;
    cls2(int v = 20)
    {
        vi = v;
    }
    cls2(cls1 p)
    {
        vi = p.vi;
    }
};

我得到的错误是:

error: 'p' has incomplete type

解决方法

使用不产生副本的引用,因此不需要完整的类声明。并拆分方法定义,将它们移动到类声明完成的地方。

class cls2;

class cls1
{
public:
    int vi;
    cls1(int v = 30)
    {
        vi = v;
    }
    cls1(const cls2& p);
};

class cls2
{
public:

    int vi;
    cls2(int v = 20)
    {
        vi = v;
    }
    cls2(const cls1& p)
    {
        vi = p.vi;
    }
};

cls1::cls1(const cls2& p)
{
    vi = p.vi;
}
,

此错误信息

error: 'p' has incomplete type

表示在构造函数定义点

cls1(cls2 p)
{
    vi = p.vi;
}

编译器还不知道类 cls2 是如何定义的以及它是否具有数据成员 vi

仅当用作参数的类是完整类型时,才能定义构造函数。

例如

class cls2;

class cls1
{
public:
    int vi;
    cls1(int v = 30)
    {
        vi = v;
    }
    cls1(cls2 p);
};

class cls2
{
public:

    int vi;
    cls2(int v = 20)
    {
        vi = v;
    }
    cls2(cls1 p)
    {
        vi = p.vi;
    }
};

cls1::cls1(cls2 p)
{
    vi = p.vi;
}

或者代替这个前向声明

class cls2;

您可以在类 cls1 的构造函数声明中使用详细的类型说明符

例如

class cls1
{
public:
    int vi;
    cls1(int v = 30)
    {
        vi = v;
    }
    cls1( class cls2 p);
};

class cls2
{
public:

    int vi;
    cls2(int v = 20)
    {
        vi = v;
    }
    cls2(cls1 p)
    {
        vi = p.vi;
    }
};

cls1::cls1(cls2 p)
{
    vi = p.vi;
}

有趣的是,使用类的构造函数可以获得意想不到的结果。

例如此声明

cls1 c{ { 10 } };

这里会叫这个constrictor

cls1(int v = 30)
{
    vi = v;
}

但是如果你再添加一对这样的大括号

cls1 c{ { { 10 } } };

然后就会调用这个构造函数

cls1::cls1(cls2 p)
{
    vi = p.vi;
}

这是一个演示程序。

#include <iostream>

class cls1
{
public:
    int vi;
    cls1(int v = 30)
    {
        std::cout << "cls1( int )\n";
        vi = v;
    }
    cls1( class cls2 p);
};

class cls2
{
public:

    int vi;
    cls2(int v = 20)
    {
        vi = v;
    }
    cls2(cls1 p)
    {
        vi = p.vi;
    }
};

cls1::cls1(cls2 p)
{
    std::cout << "cls1( cls2 )\n";
    vi = p.vi;
}

int main()
{
    cls1 c1 { { 10 } };
    cls1 c2 { { { 10 } } }; 

    // or
    // cls1 c1 { { } };
    // cls1 c2 { { { } } }; 
}

程序输出为

cls1( int )
cls1( cls2 )
,

发生错误是因为构造函数需要知道如何复制 cls2 对象。您可以通过在 cls1 声明之后移动 cls2 构造函数实现来解决此问题:

class cls2;

class cls1
{
public:
    int vi;
    cls1(int v = 30)
    {
        vi = v;
    }
    cls1(cls2 p);
};

class cls2
{
public:

    int vi;
    cls2(int v = 20)
    {
        vi = v;
    }
    cls2(cls1 p)
    {
        vi = p.vi;
    }
};


cls1::cls1(cls2 p) {
    vi = p.vi;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。