【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. Java如何对List集合的操作方法(二)

    4.list中查看(判断)元素的索引: 注意:.indexOf(): 和  lastIndexOf()的不同:   ///*************************************** ...

  2. ios 10 新特性

    UITextField添加了textContentType枚举,指示文本输入区域所期望的语义意义. 使用此属性可以给键盘和系统信息,关于用户输入的内容的预期的语义意义. 当您提供有关您期望用户在文本输 ...

  3. SVN服务的模式和多种访问方式 多种访问原理图解与优缺点

    SVN企业应用场景 SVN任是当前企业的主流.git正在发展,未来会成为主流.如果大家精力足够,建议同时掌握. 1.4运维人员掌握版本管理 对于版本管理系统,运维人员需要掌握的技术点: 1.安装.部署 ...

  4. sql语句优化(一)

    1.查看执行时间和cpu占用时间 set statistics time on select * from dbo.Product set statistics time off 2.查看查询对I/0 ...

  5. 万恶之源 - Python装饰器及内置函数

    装饰器 听名字应该知道这是一个装饰的东西,我们今天就来讲解一下装饰器,有的铁子们应该听说,有的没有听说过.没有关系我告诉你们这是一个很神奇的东西 这个有多神奇呢? 我们先来复习一下闭包 def fun ...

  6. eclipse中Tomcat服务器缓存位置,以及清理Tomcat缓存

    在Eclipse中进行Web开发,一般都会将项目直接在Eclipse中的Tomcat服务器运行,有时候修改了程序和页面之后,运行结果还是原来的 tomcat服务器中缓存的程序或者页面,需要清理缓存之后 ...

  7. 无法连接 MKS:套接字连接尝试次数太多正在放弃

    我的电脑 -> 右键 -> 管理 -> 服务和应用程序 -> 服务: 开启下面的服务: 服务启动成功后,重启虚拟机; 或者先挂起虚拟机,等服务启动后,继续运行挂起的虚拟机:

  8. Linux开启root用户

    1.进入系统的时候Ctrl + Alt + F1,切换到命令窗口,登录现有用户: 2.执行sudo passwd root + root的密码: 3.按照要求输入密码: ==> root用户密码 ...

  9. 使用spring的aop对Struts2的Action拦截后出现依赖注入为空问题

    两种解决方案: 1.action类继承ActionSupport了后,出现依赖注入为空,要在applicationContext.xml配置中加入:<aop:aspectj-autoproxy ...

  10. 部分还款-还款试算接口与还款接口-python

    一.还款试算.还款接口, 1.只传入参数loan_Code 2.还款接口参数化以下: "loanCode": loanCode1,"orderId": orde ...