c++学习-类的前置声明与使用头文件区别

今天在看Leveldb源码的时候,发现作者使用了很多前置声明,这个语法之前关注的不是很多,今天稍微总结下。
主要参考了下面文章:
[关于C++中的前置声明]

什么时候用

  1. 一般是用头文件来声明要使用的新类型,但是当两个头文件形成环的时候可以使用类的前置声明来破除环。
  2. 我看leveldb源码的时候,作者大量使用前置声明,并不是因为这个原因,忘了在哪看到过,在此处使用前置声明的原因应该是:前置 引用声明比头文件节省了大量的代码长度。
  3. 但是,前置引用声明使用的时候有很大的限制就是只能使用类的引用或者指针,因为前置声明只是声明,不是类的定义,没有办法去定义对象,自然也就不能访问类的方法。
  4. 感觉这样做,头文件可以清晰一点。把实现放到源文件里面去。

代码

先给出错误的示范:考虑写一个四则运算的运算符类,以及操作数类。

// Opnd.h
#ifndef OPND_H_
#define OPND_H_

class Opnd {
public:
    Opnd(){ a_ = 0; }
    Opnd( int x ) : a_(x) {}

    int get_a() const { return a_; }

private:
    int a_;
};


#endif
// Optr.h
#ifndef OPTR_H_
#define OPTR_H_
#include <cassert>

class Opnd; // 前置声明

class Optr{
public:
    Optr( char c = '+' ) : op(c) {}

    int compute( const Opnd& left, const Opnd& right ){ // 正确使用
        int ans = 0;
        int lvalue = left.get_a();// 错误使用,前置声明只是声明,不是定义,所以不能使用类方法
        int right = right.get_a();// 错误使用
        switch( op ){
            case '+' : ans = lvalue + rvalue; break;
            case '-' : ans = lvalue - rvalue; break;
            case '*' : ans = lvalue * rvalue; break;
            case '/' : assert(right != 0); ans = lvalue / rvalue; break;
        }
        return ans;
    }

private:
    char op;
};

#endif

下面给出正确的示范:

// Opnd.h
#ifndef OPND_H_
#define OPND_H_

class Opnd {
public:
    Opnd(){ a_ = 0; }
    Opnd( int x ) : a_(x) {}

    int get_a() const { return a_; }

private:
    int a_;
};
// Optr.h
#ifndef OPTR_H_
#define OPTR_H_
#include <cassert>

class Opnd; // 前置声明

class Optr{
public:

    Optr( char c = '+' ) : op(c) {}

    int compute( const Opnd& left, const Opnd& right ); // 使用正确

private:
    char op;
};

#endif

实现放到源文件里面去。

// Optr.cpp
#include <cassert>
#include "Optr.h"
#include "Opnd.h"

int Optr::compute( const Opnd& left, const Opnd& right ){
    int ans = 0;
    int lvalue = left.get_a();
    int rvalue = right.get_a();
    switch( op ){
        case '+' : ans = lvalue + rvalue; break;
        case '-' : ans = lvalue - rvalue; break;
        case '*' : ans = lvalue * rvalue; break;
        case '/' : assert(rvalue != 0); ans = lvalue / rvalue; break;
    }
    return ans;
}
// main.cpp
#include "Optr.h"
#include "Opnd.h"
#include <iostream>

int main( void ){

    Opnd opnd1(3);
    Opnd opnd2(4);

    Optr opt('+');
    std::cout << opt.compute( opnd1, opnd2 ) << std::endl;

    return 0;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值