读书人

c++ 等等的前置声明

发布时间: 2012-09-07 10:38:15 作者: rapoo

c++ 之类的前置声明

?

转自:http://blog.csdn.net/fjb2080/archive/2010/04/27/5533514.aspx?作者:清林,博客名:飞空静渡

刚开始学习c++的人都会遇到这样的问题:

定义一个类 class A,这个类里面使用了类B的对象b,然后定义了一个类B,里面也包含了一个类A的对象a,就成了这样:

?

????????????C&?doToC(C&);
c++ 等等的前置声明????????????C&?doToC2(C&?c)?{return?doToC(c);};


从上面的代码来看,A的一个成员函数doToC2调用了另外一个成员函数doToC,但是无论是doToC2,还是doToC,它们的的参数和返回类型其实都是C的引用(换成指针,情况也一样),引用的赋值跟指针的赋值都是一样,无非就是整形的赋值,所以这里即不需要知道C的大小也没有调用C的任何函数,实际上这里并不需要C的定义。

但是,我们随便把其中一个C&换成C,比如像下面的几种示例:

c++ 等等的前置声明??????????? 1.
??? ??? ??? ??? C&?doToC(C&);
c++ 等等的前置声明????????????C&?doToC2(C?c)?{return?doToC(c);};
??? ?? ?? ?? ???
??? ?? ?? ?? ?? 2.
??????????? ??? C& doToC(C);
??????????? ??? C& doToC2(C& c) {return doToC(c);};

??? ?? ?? ?? ?? 3.
??? ?? ?? ?? ???C?doToC(C&);
??????????? ??? C& doToC2(C& c) {return doToC(c);};

??? ?? ?? ?? ?? 4.
??? ?? ?? ?? ?? C& doToC(C&);
??????????? ????C?doToC2(C& c) {return doToC(c);};


无论哪一种,其实都隐式包含了一个拷贝构造函数的调用,比如1中参数c由拷贝构造函数生成,3中doToC的返回值是一个由拷贝构造函数生成的匿名对象。因为我们调用了C的拷贝构造函数,所以以上无论那种情形都需要知道C的定义。

9和10都一样,我们都不需要知道C的定义,只是10的情况下,前置声明的语法会稍微复杂一些。
最后给出一个完整的例子,我们可以看到在两个不同名字空间的类型A和C,A是如何使用前置声明来取代直接包括C的头文件的:
A.h

#pragma once#include <list>#include <vector>#include <map>#include <utility>    //不同名字空间的前置声明方式namespace test1{          class C;}namespace test2{          //用using避免使用完全限定名    using test1::C;        class A     {    public:                C   useC(C);            C& doToC(C&);            C& doToC2(C& c) {return doToC(c);};                             private:            std::list<C>    _list;            std::vector<C>  _vector;            std::map<C, C>  _map;            C*              _pc;            C&              _rc;        };}
?



C.h

#ifndef C_H#define C_H#include <iostream>namespace test1{              class C    {    public:           void print() {std::cout<<"Class C"<<std::endl;}    };}#endif // C_H
?

读书人网 >C++

热点推荐