• C++前置声明


    【1】一般的前置函数声明

    见过最多的前置函数声明,基本格式代码如下:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void fun(char ch, int *pValue, double dValue);
     5 
     6 void main()
     7 {
     8     int nValue = 100;
     9     double dValue = 111.22;
    10     fun('a', &nValue, dValue);
    11 
    12     system("pause");
    13 }
    14 
    15 void fun(char ch, int *pValue, double dValue)
    16 {
    17     return;
    18 }

    很好理解,不做赘述。

    【2】自定义类型的前置声明

    自定义类型的前置声明,由于编译器不知道类型的大小,所以不可以声明类型的对象。只可以利用类型声明指针和引用。

    代码如下:

     1 /*
     2  * 自定义类型前置声明
     3  */
     4 #include <iostream>
     5 using namespace std;
     6 
     7 class B;
     8 
     9 class A 
    10 {
    11 private:
    12     // 内置类型
    13     int m_nInt;
    14     int& m_nRInt;
    15     int* m_pInt;
    16 
    17     // 自定义类型
    18 //    B b; // error!
    19     B* m_pB;
    20     B& m_b;
    21 
    22 public:  
    23     A (B *pBPara = NULL) : m_nInt(100)
    24         , m_nRInt(m_nInt)
    25         , m_pInt(NULL)
    26         , m_pB(NULL)
    27         , m_b((NULL == pBPara) ? (*m_pB) : (*pBPara))
    28     {
    29         cout << "A()" << endl;
    30     }
    31     ~A()
    32     {
    33         cout << "~A()" << endl;
    34     }
    35 
    36     void funA()
    37     {
    38 //        m_pB->doAnything(); // build error C2027: use of undefined type 'B'
    39     }
    40 };
    41 
    42 class B
    43 {
    44 private:
    45     int m_n;
    46 
    47 public:  
    48     B (int n = 100) : m_n(n)
    49     {
    50         cout << "B()" << endl;
    51     }
    52     ~B()
    53     {
    54         cout << "~B()" << endl;
    55     }
    56     void doAnything()
    57     {
    58         cout << "B::anythig()" << endl;
    59     }
    60 };
    61 
    62 void main()
    63 {
    64     A objA;
    65     system("pause");
    66 }

    如上,利用前置类型的指针想调用其成员函数,会报编译错误!那么,肿么办?请看下文。

    【3】声明和实现分离

    代码如下,声明头文件:

     1 /*
     2  * TestForwardDeclar.h
     3  */
     4 #ifndef D_TESTFORWARDDECLAR_H_
     5 #define D_TESTFORWARDDECLAR_H_
     6 
     7 #include <iostream>
     8 
     9 class B;  // 前置声明自定义类型
    10 
    11 class A 
    12 {
    13 private:
    14     // 内置类型
    15     int m_nInt;
    16     int& m_nRInt;
    17     int* m_pInt;
    18 
    19     // 自定义类型
    20 //    B b; // error!
    21     B* m_pB;
    22     B& m_b;
    23 
    24 public:  
    25     A (B *pBPara = NULL);
    26     ~A ();
    27     void funA();
    28 };
    29 
    30 class B
    31 {
    32 private:
    33     int m_n;
    34 
    35 public:  
    36     B (int n = 100);
    37     ~B ();
    38     void doAnything();
    39 };
    40 
    41 #endif

    代码如下,定义文件:

     1 /*
     2  * TestForwardDeclar.cpp
     3  */
     4 
     5 #include "TestForwardDeclar.h"
     6 #include <iostream>
     7 
     8 A::A (B *pBPara) 
     9     : m_nInt(100)
    10     , m_nRInt(m_nInt)
    11     , m_pInt(NULL)
    12     , m_pB(NULL)
    13     , m_b((NULL == pBPara) ? (*m_pB) : (*pBPara))
    14 {
    15     std::cout << "A()" << std::endl;
    16 }
    17 
    18 A::~A()
    19 {
    20     std::cout << "~A()" << std::endl;
    21 }
    22 
    23 void A::funA()
    24 {
    25     m_pB->doAnything();  // 分开头文件和实现文件即可
    26 }
    27 
    28 
    29 B::B (int n) : m_n(n)
    30 {
    31     std::cout << "B()" << std::endl;
    32 }
    33 
    34 B::~B()
    35 {
    36     std::cout << "~B()" << std::endl;
    37 }
    38 
    39 void B::doAnything()
    40 {
    41     std::cout << "B::anythig()" << std::endl;
    42 }

    代码如下:测试文件:

    1 #include "TestForwardDeclar.h"
    2 
    3 void main()
    4 {
    5     A objA;
    6 }

    编译成功,运行结果是期望效果。

    【4】总结

    自定义类型前置声明时,只可以利用类型名声明指针和引用变量(谨记不可以声明对象或new 对象,均因为类型大小不确定,编译器无能为力)。

    若需要利用指针或引用调用前置类型的接口,必须按照声明和实现分离的方式进行编码。

    Good Good Study, Day Day Up.

    顺序 选择 循环 总结

  • 相关阅读:
    DB2 导入CSV文件
    非归档模式下丢失数据文件,怎么办
    制作U盘操作系统安装盘
    Oracle 发布 NoSQL 数据库
    【转载】VMWare Workstation 支持64位操作系统
    net下多个应用之间的web.config冲突的解决办法(禁止继承)
    \r\n 的真切含义
    VMware虚拟机中调整Linux分区大小手记
    磨刀不光不误切菜功,还能强身健体
    农夫送狼羊白菜过河_题目收集
  • 原文地址:https://www.cnblogs.com/Braveliu/p/6653941.html
Copyright © 2020-2023  润新知