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

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

 #include <iostream>
using namespace std; void fun(char ch, int *pValue, double dValue); void main()
{
int nValue = ;
double dValue = 111.22;
fun('a', &nValue, dValue); system("pause");
} void fun(char ch, int *pValue, double dValue)
{
return;
}

很好理解,不做赘述。

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

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

代码如下:

 /*
* 自定义类型前置声明
*/
#include <iostream>
using namespace std; class B; class A
{
private:
// 内置类型
int m_nInt;
int& m_nRInt;
int* m_pInt; // 自定义类型
// B b; // error!
B* m_pB;
B& m_b; public:
A (B *pBPara = NULL) : m_nInt()
, m_nRInt(m_nInt)
, m_pInt(NULL)
, m_pB(NULL)
, m_b((NULL == pBPara) ? (*m_pB) : (*pBPara))
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
} void funA()
{
// m_pB->doAnything(); // build error C2027: use of undefined type 'B'
}
}; class B
{
private:
int m_n; public:
B (int n = ) : m_n(n)
{
cout << "B()" << endl;
}
~B()
{
cout << "~B()" << endl;
}
void doAnything()
{
cout << "B::anythig()" << endl;
}
}; void main()
{
A objA;
system("pause");
}

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

【3】声明和实现分离

代码如下,声明头文件:

 /*
* TestForwardDeclar.h
*/
#ifndef D_TESTFORWARDDECLAR_H_
#define D_TESTFORWARDDECLAR_H_ #include <iostream> class B; // 前置声明自定义类型 class A
{
private:
// 内置类型
int m_nInt;
int& m_nRInt;
int* m_pInt; // 自定义类型
// B b; // error!
B* m_pB;
B& m_b; public:
A (B *pBPara = NULL);
~A ();
void funA();
}; class B
{
private:
int m_n; public:
B (int n = );
~B ();
void doAnything();
}; #endif

代码如下,定义文件:

 /*
* TestForwardDeclar.cpp
*/ #include "TestForwardDeclar.h"
#include <iostream> A::A (B *pBPara)
: m_nInt()
, m_nRInt(m_nInt)
, m_pInt(NULL)
, m_pB(NULL)
, m_b((NULL == pBPara) ? (*m_pB) : (*pBPara))
{
std::cout << "A()" << std::endl;
} A::~A()
{
std::cout << "~A()" << std::endl;
} void A::funA()
{
m_pB->doAnything(); // 分开头文件和实现文件即可
} B::B (int n) : m_n(n)
{
std::cout << "B()" << std::endl;
} B::~B()
{
std::cout << "~B()" << std::endl;
} void B::doAnything()
{
std::cout << "B::anythig()" << std::endl;
}

代码如下:测试文件:

 #include "TestForwardDeclar.h"

 void main()
{
A objA;
}

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

【4】总结

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

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

Good Good Study, Day Day Up.

顺序 选择 循环 总结

C++前置声明的更多相关文章

  1. C++ 类的前置声明

    http://www.2cto.com/kf/201311/260705.html    今天在研究C++”接口与实现分离“的时候遇到了一个问题,看似很小,然后背后的东西确值得让人深思!感觉在学习的过 ...

  2. C++中头文件相互包含与前置声明

    一.类嵌套的疑问 C++头文件重复包含实在是一个令人头痛的问题,前一段时间在做一个简单的数据结构演示程序的时候,不只一次的遇到这种问题.假设我们有两个类A和B,分别定义在各自的有文件A.h和B.h中, ...

  3. C++ 前置声明 和 包含头文件 如何选择

    假设有一个Date类 Date.h class Date { private: int year, month, day; }; 如果有个Task类的定义要用到Date类,有两种写法 其一 Task1 ...

  4. C++_前置声明

    为什么要有前置声明? eg: -定义一个类 class A,这个类里面使用了类B的对象b,然后定义了一个类B,里面也包含了一个类A的对象a,就成了这样: //a.h #include "b. ...

  5. 关于C++中的前置声明(附程序运行图)

    实验于华中农业大学逸夫楼2017.3.10 在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration).下面的程序中,带注释的那行就是类B的前置说明.这是必须的,因为类A中 ...

  6. C++ 类声明 类前置声明范例

    转载自http://www.cnblogs.com/staring-hxs/p/3244251.html 在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration).下面的 ...

  7. 【C++】类前置声明范例

    • 在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration).下面的程序中,带注释的那行就是类B的前置说明.这是必须的,因为类A中用到了类B,而类B的声明出现在类A的后面 ...

  8. C++中前置声明介绍

    前置声明是指对类.函数.模板或者结构体进行声明,仅仅是声明,不包含相关具体的定义.在很多场合我们可以用前置声明来代替#include语句. 类的前置声明只是告诉编译器这是一个类型,但无法告知类型的大小 ...

  9. c++中的前置声明

    引用google c++编码规范: When you include a header file you introduce a dependency that will cause your cod ...

随机推荐

  1. Webpack傻瓜式指南(转)

    add by zhj: 作者写了三篇文章,这是第一篇幅,另外两篇参见 https://zhuanlan.zhihu.com/p/20397902 https://zhuanlan.zhihu.com/ ...

  2. centos7.2 mysql5.5编译安装

    环境 centos7.2 源码包mysql5.5.38 mysql5.5开始,源码配置编译工具configure变成了cmake,所以先要去把cmake装上.并安装make,bison,cmake,g ...

  3. Linux软件包的安装(rpm+yum)

    概述: 1.rpm软件包管理命令软件包的获取a.光盘镜像中有很多软件包可以使用:先挂载光盘,再查看软件包b.从软件的官网获取 .rpm 安装rpm包 ipm -ivh 软件包名称删除rpm包 ipm ...

  4. 客户机容易随机出现自动重启、游戏卡问题?不妨优化下BIOS中节能技术!

    相信一些玩主板超频的人都知道,给CPU加电压能够提升CPU的处理速度,很多超频爱好者通过采购超频性能较好,且价格较低的主板和CPU来玩超频,并且通过一些参数的问题能让屌丝设备发挥出高富帅的性能.但是玩 ...

  5. url映射

    #include<iostream> #include<algorithm> #include<ctype.h> #include<string> #i ...

  6. mac chrome 浏览器开启允许跨域

    在控制台输入下面代码: open -n /Applications/Google\ Chrome.app/ --args --disable-web-security  --user-data-dir ...

  7. Ajax 传包含集合的JSON

    通过ajax给后台传json对象,当json中含对象集合时,如 $.ajax({ url : , type : "POST", dataType : "json" ...

  8. delete 删除对象属性

    删除属性要直接删.

  9. app刷新

    https://segmentfault.com/a/1190000006733978 优化TCP socket参数,包括:是否关闭快速回收.初始RTO.初始拥塞窗口.socket缓存大小.Delay ...

  10. @Value("#{}") 和 @Value("{}")

    1 @Value("#{}")   SpEL表达式 @Value("#{}") 表示SpEl表达式通常用来获取bean的属性,或者调用bean的某个方法.当然还 ...