zoukankan      html  css  js  c++  java
  • C++学习之路: 前向申明

    引言:

      有种特殊情况,当两个类需要相互引用形成一个”环形“引用时,无法先定义使用。 这时候需要用到前向申明

    但是前向申明的类不能实例化。

     1 #pragma once
     2 
     3 #include "B.h"
     4 class A
     5 {
     6 public:
     7     A();
     8     ~A();
     9 
    10     B b_;
    11 };
    #pragma once
    #include "A.h"
    class B
    {
    public:
        B();
        ~B();
    
        A a_;
    };

    两个类互相包含编译的提示错误为:

    1 1>------ 已启动生成:  项目: test, 配置: Debug Win32 ------
    2 1>  B.cpp
    3 1>g:cpp代码	est	esta.h(10): error C2146: 语法错误: 缺少“;”(在标识符“b_”的前面)
    4 1>g:cpp代码	est	esta.h(10): error C4430: 缺少类型说明符 - 假定为 int。注意:  C++ 不支持默认 int
    5 1>  A.cpp
    6 1>g:cpp代码	est	est.h(9): error C2146: 语法错误: 缺少“;”(在标识符“a_”的前面)
    7 1>g:cpp代码	est	est.h(9): error C4430: 缺少类型说明符 - 假定为 int。注意:  C++ 不支持默认 int
    8 1>  正在生成代码...
    9 ========== 生成:  成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

    那么什么是前向申明呢?

    #pragma once
    #include "A.h"
    
    class A;  //前向申明
    class B
    {
    public:
        B();
        ~B();
    
        A a_;  //不可实例化
    };

    这样仍然是错误的,因为前向申明是不可实例化的。 

    编译提示:

    1>------ 已启动生成:  项目: test, 配置: Debug Win32 ------
    1>  B.cpp
    1>g:cpp代码	est	esta.h(10): error C2146: 语法错误: 缺少“;”(在标识符“b_”的前面)
    1>g:cpp代码	est	esta.h(10): error C4430: 缺少类型说明符 - 假定为 int。注意:  C++ 不支持默认 int
    1>  A.cpp
    1>g:cpp代码	est	est.h(11): error C2079: “B::a_”使用未定义的 class“A”
    1>  正在生成代码...
    ========== 生成:  成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

    很简单的处理,只需要使用指针即可。 经过试验 引用也可。

     1 #pragma once
     2 #include "A.h"
     3 
     4 class A;
     5 class B
     6 {
     7 public:
     8     B();
     9     ~B();
    10 
    11     A *a_;
    12 };

    嵌套类:Demo

     1 #include <iostream>
     2 using namespace std;
     3 
     4 
     5 class Outer
     6 {
     7     class Inner
     8     {
     9     public:
    10         void fun()
    11         {
    12             cout << "Inner:Fun...." << endl;
    13         }
    14     };
    15 
    16 public:
    17     Inner obj_;
    18     void fun()
    19     {
    20         cout << "Outer:fun..." << endl;
    21         obj_.fun();
    22     }
    23 
    24 };
    25 
    26 int main(void)
    27 {
    28     Outer o;
    29     o.fun();
    30 }

    ## 从作用域的角度看,嵌套类被影藏在外围类中,该类名只能在外围类中使用。如果在外围类的作用域中使用该类名时,需要加名字限定;

    ##嵌套类中的成员函数可以再它的类体外定义;

    ##嵌套类的成员函数对外围类的的成员没有访问权,反之亦然。

    ##嵌套类仅仅是语法上的嵌入

     1 #include <iostream>
     2 using namespace std;
     3 
     4 
     5 class Outer
     6 {
     7     class Inner
     8     {
     9     public:
    10         void fun();
    11     };
    12 
    13 public:
    14     Inner obj_;
    15     void fun()
    16     {
    17         cout << "Outer:fun..." << endl;
    18         obj_.fun();
    19     }
    20 
    21 };
    22 void Outer::Inner::fun()
    23 {
    24     cout << "Inner:Fun...." << endl;
    25 }
    26 
    27 int main(void)
    28 {
    29     Outer o;
    30     o.fun();
    31 }

    类体外申明只需要记住要加多个类名即可。

  • 相关阅读:
    【Log历练手册】Spring事务管理不能提交异常
    【网络安全】如何使用OpenSSL工具生成根证书与应用证书
    【网络安全】如何使用OpenSSL工具生成根证书与应用证书
    【JAVA笔记——器】Spring Aop 实现Log日志系统——基本实现
    jdbc连接池配置方法
    用于读/写配置的工具,下面列出了各种配置(从最高优先级到最低优先级)
    文件复制Util写法,可以适用于多种条件
    记录一个工作中遇到的问题,svn拉的项目,pom.xml报错
    layui的js写法,部分代码
    JDBCUtil连接数据库的写法
  • 原文地址:https://www.cnblogs.com/DLzhang/p/4584416.html
Copyright © 2011-2022 走看看