V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Newyorkcity
V2EX  ›  问与答

c++似乎不允许把自定义的类作为另一个类的构造器的参数?

  •  
  •   Newyorkcity · 2018-12-11 18:29:26 +08:00 · 1141 次点击
    这是一个创建于 2204 天前的主题,其中的信息可能已经有所发展或是发生改变。

    废话不多说,直接晒出全部代码,也很简洁..

    --------------------

    main.cpp

    #include <iostream>
    #include "statement.h"
    int main(int argc, char **argv) {
    	return 0;
    }
    

    statement.h --- 这个头文件将另外另个类的头文件都 include 进来

    #ifndef _STATEMENT_H_
    #define _STATEMENT_H_
    #include "testA.h"
    #include "testB.h"
    #endif // !_STATEMENT_H_
    

    testA.h --- 这个文件是 testA 类的头文件

    #ifndef _TESTA_H_
    #define _TESTA_H_
    #include "statement.h"
    class testA
    {
    public:
    	testA(testB b);
    private:
    };
    #endif // !_TEST_A_
    

    testA.cpp --- 对应 testA.h

    #include "testA.h"
    testA::testA(testB b)
    {
    	//pass
    }
    

    testB 类的头文件和 cpp 和 testA 一模一样,这里干脆就不复制粘贴了,简单来说就是啥具体内容都没有..

    然后编译不通过,是 VS2017,错误代码都是 C2061,『语法错误:标识符 testB 』出现两次,『语法错误:标识符 testA 』出现一次.

    请问这个错误是为何?为什么要阻止这样的行为?应该怎么做?

    谢谢

    第 1 条附言  ·  2018-12-11 19:33:50 +08:00
    现在将构造器中的参数全部变为指针
    testA * a
    testB * b
    当然 cpp 文件中的参数表也同样调整,函数体里还是什么都没有
    仍然无法通过编译,错误提示一模一样..
    第 2 条附言  ·  2018-12-11 19:56:14 +08:00
    给大家添麻烦了,主要就是『 innoink 』和『 wbing 』两位指出的问题
    按照我这个 include 方式,testA 与 testB 总是要有先后顺序的,而在前面的那个类的构造函数里的 test?就不知道是什么玩意儿了
    解决方法的话就是在最最最最前面单纯的放一个
    class testA;
    class testB;
    问题就迎刃而解,不用指针都一样可以通过编译.
    13 条回复    2018-12-11 20:25:38 +08:00
    wbing
        1
    wbing  
       2018-12-11 18:41:10 +08:00 via iPhone   ❤️ 2
    你在声明 A 的时候用到了 B,声明 B 的时候又用到了 A。
    加个前置声明试试。在 testA.h 第三行之后放一行 class testB;
    innoink
        2
    innoink  
       2018-12-11 18:57:06 +08:00   ❤️ 2
    @wbing 他这个没办法,前置声明只能用与传指针的情况。否则 testb 的大小不知道,没办法编译生成最终传参代码。
    feverzsj
        3
    feverzsj  
       2018-12-11 19:03:38 +08:00
    你这是 java 写多了
    Newyorkcity
        4
    Newyorkcity  
    OP
       2018-12-11 19:16:53 +08:00
    @innoink 那请问有没有什么办法实现这种想法呢?谢谢
    Newyorkcity
        5
    Newyorkcity  
    OP
       2018-12-11 19:21:03 +08:00
    @innoink 噢,参数要求那种类的指针对吧!
    innoink
        6
    innoink  
       2018-12-11 19:21:58 +08:00 via Android
    @Newyorkcity 改成引用或者指针传参数,然后使用前置声明
    innoink
        7
    innoink  
       2018-12-11 19:25:49 +08:00 via Android   ❤️ 1
    其实本质上,你这个 testb 的头文件就不可能 include 进来。
    main.cpp 中 include 了 statement.h,即定义了_STATEMENT_H_,然后 statement.h 中 include 了 testA.h,testA.h 中又 include 了 statement.h,你是想在这里把 testB.h 包含进来,但是_STATEMENT_H_在 main.cpp 那里已经定义,这个 include 就“失败”了,testB.h 最终不会进来
    exonuclease
        8
    exonuclease  
       2018-12-11 19:26:56 +08:00 via iPhone
    你就拿个引用不就行了 没看懂你要干嘛
    Newyorkcity
        9
    Newyorkcity  
    OP
       2018-12-11 19:32:39 +08:00
    @innoink 这个应该不是问题吧,statement.h 中也 include 了 testB.h,include testA.h 的时候 testA 里不会再 include testB.h 没关系,之后 statement.h 还有一个 include testB.h 要执行,这一步会把 testB include 进来的吧
    innoink
        10
    innoink  
       2018-12-11 19:36:10 +08:00 via Android
    @Newyorkcity 对,我说的有问题,testB 不会在 testA 之前出现
    Newyorkcity
        11
    Newyorkcity  
    OP
       2018-12-11 19:39:27 +08:00
    @innoink 那其实不管是怎么 include,总归是有一个先后顺序的,我这里 testA 构造函数要用 testB,testB 构造函数要用 testA,总有一个类的头文件在另一个类的头文件的内容的后面...

    @wbing 诶卧槽,所以我试了一下把 class testA;放在 testB 类声明上面一行和 class testB;放在 testA 类声明上面一行,问题就解决了!~
    innoink
        12
    innoink  
       2018-12-11 20:06:29 +08:00 via Android
    @Newyorkcity 对了,你这个构造函数放在单独的 cpp 文件,是可以直接前置声明的,因为函数声明不需要知道完整的类型定义。。。
    iceheart
        13
    iceheart  
       2018-12-11 20:25:38 +08:00 via Android
    递归包含的,先踹一脚。
    C 风格的代码就用指针或者引用
    C++风格的就用抽象类
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2556 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 15:41 · PVG 23:41 · LAX 07:41 · JFK 10:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.