📄 《c++编程思想》-- 第5章 笔记.txt
字号:
作者:rick1126
email: rickzhang@sina.com
日期:7/31/2001 10:11:18 PM
第5章 函数重载和缺省参数
5.0 基本概念
【名字】
. 能使名字方便地使用是任何程序设计语言的一个重要特征
. 依靠系统描述的名字, 才可以写出人们易于理解和修改的程序
. 问题在于如何将语言的细微差别的概念映射到编程语言 -- 例如一词多意的情况
【函数重载】
. 使用相同的函数名称不同的参数列表和返回值类型作为重载的区分依据
. 重载构造函数可以使用多种不同的方式初始化类对象实例
【缺省参数】
. 针对冗长或者重复的函数调用参数, 使用缺省值的方式减少输入的烦琐和可能的错误
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5.1 范围分解
【编译器对于重载函数名称的处理】
. 函数名不仅与类名关系密切, 而且还跟其他因素相关
. 重载函数要求参数不同, 而且不能利用返回值进行重载
. 同名函数要么是范围不同, 要么是重载函数, 编译器总是生成不同的内部名称
【安全类型连接】
. 在C下允许函数没有声明直接调用,为此可能导致编译器按照调用方式推断函数声明, 造成难以发现的错误
. 在C++中不允许函数没有声明就被使用, 名词分解提供了一个安全连接
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5.3 缺省参数
【缺省参数】
. 在函数声明的时候给定出初始值, 调用的时候如果没有给出指定值, 编译器就使用初始值代替.
. 相关使用规则:
- 参数列表的后部参数才可以是缺省的, 否则编译器无法根据位置判断, 缺省值后面必须全部是缺省参数
- 而且如果有多个缺省参数存在, 而相对后面一个值需要指定, 则前面的都需要给出, 即使就是缺省的
. 这样如果发现缺省参数不在需要可以简单的去掉而不影响以前的版本使用.
【位向量类】
标志位位串是一个在接收序列的时候特别是类似UDP数据包的时候经常用到的, 表示第几个数据包已经接收, 未接收等. 如果使用一个int, unsigned char...的数组有时候显然效率不高, 资源浪费. 所以使用位串最好, 因为使用位操作效率较高, 而位串占用内存也较少.
// Flags.h: interface for the CFlags class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_FLAGS_H__0FCB90C7_E5D7_4764_A16A_82B84BA310D9__INCLUDED_)
#define AFX_FLAGS_H__0FCB90C7_E5D7_4764_A16A_82B84BA310D9__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "stdio.h"
#include "string.h"
#include "assert.h"
#define FALSE 0
#define TRUE 1
#define FSIZE 100
class CFlags
{
private:
unsigned char f[FSIZE];
public:
CFlags();
virtual ~CFlags();
void set( int i);
void clear( int i);
int read( int i );
int size();
};
#endif // !defined(AFX_FLAGS_H__0FCB90C7_E5D7_4764_A16A_82B84BA310D9__INCLUDED_)
// Flags.cpp: implementation of the CFlags class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Flags.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFlags::CFlags()
{
memset( f, FALSE, FSIZE );
}
CFlags::~CFlags()
{
}
void CFlags::set( int i )
{
assert( i>=0 && i<FSIZE );
f[i] = TRUE;
}
void CFlags::clear( int i )
{
assert( i>=0 && i<FSIZE );
f[i] = FALSE;
}
int CFlags::read( int i )
{
assert( i>=0 && i<FSIZE );
return f[i];
}
int CFlags::size()
{
return FSIZE;
}
//BitVector.h
#ifndef BITVECT_H
#define BITVECT_H
class CBitVector{
unsigned char* bytes;
int Bits, numBytes;
public:
CBitVector();
CBitVector( unsigned char* init, int size=8 );
CBitVector( char* binary );
~CBitVector();
void set( int bit );
void clear( int bit );
int read( int bit );
int bits();
void bits( int sz );
void print( const char* msg="" );
};
#endif//BITVECT_H
//BitVector.cpp
#include "stdafx.h"
#include "bitvector.h"
#include "stdio.h"
#include "assert.h"
#include "stdlib.h"
#include "string.h"
#include "limits.h"
//描述: 获得一个只有字节长度最高位1的一个无符号字节的掩码
const unsigned char highbit = 1 << (CHAR_BIT - 1);
//将所有变量赋值0
CBitVector::CBitVector()
{
numBytes = 0;
}
//描述: 分配内存并初始化位数
CBitVector::CBitVector( unsigned char* init, int size )
{
//设置字节数
numBytes = size;
//设置比特位数
Bits = numBytes * CHAR_BIT;
//根据字节数分配一个元素长度为1字节, 个数为字节数的数组
bytes = ( unsigned char* )calloc( numBytes, 1 );
assert( bytes );
//如果指针空直接返回
if ( init==0 ) return;
//按比特位赋值
for( int index=0; index<numBytes; index++ ){
for( int offset=0; offset<CHAR_BIT; offset++ ){
set( index * CHAR_BIT + offset );
}
}
}
//描述: 将一个2进制0,1序列转换成为BitVector
CBitVector::CBitVector( char* binary )
{
//获得比特位数和对应字节数, 这里输入的binary使用整整一个字节代表一个比特位
Bits = strlen( binary );
numBytes = Bits/CHAR_BIT;
if ( Bits%CHAR_BIT )
numBytes++;
//分配内存并且按位赋值
bytes = ( unsigned char* )calloc( numBytes,1 );
assert( bytes );
for( int i=0; i<Bits; i++ ){
if ( binary[i] == '1' )
set(i);
}
}
//描述: 释放内存
CBitVector::~CBitVector()
{
free( bytes );
}
//描述: 按位赋值
void CBitVector::set( int bit )
{
assert( bit>=0 && bit<Bits );
int index=bit/CHAR_BIT;
int offset = bit%CHAR_BIT;
unsigned char mask = ( 1<<offset );
bytes[index]|=mask;
}
//描述: 获得指定比特位的赋值
int CBitVector::read( int bit )
{
assert( bit>=0 && bit<Bits );
int index=bit/CHAR_BIT;
int offset = bit%CHAR_BIT;
unsigned char mask = ( 1<<offset );
return bytes[index]&mask;
}
//描述: 清除指定位的值
void CBitVector::clear( int bit )
{
assert( bit >= 0 && bit < Bits );
int index=bit/CHAR_BIT;
int offset = bit%CHAR_BIT;
unsigned char mask = ( 1<<offset );
bytes[index]&=mask;
}
//描述: 得到比特位数
int CBitVector::bits()
{
return Bits;
}
void CBitVector::bits( int sz )
{
int oldsize = Bits;
Bits = sz;
numBytes = Bits/CHAR_BIT;
if ( Bits%CHAR_BIT )
numBytes ++;
void* v = realloc( bytes, numBytes );
assert(v);
bytes = (unsigned char*) v;
for ( int i=oldsize; i<Bits; i++ )
clear( i );
}
//描述: 打印信息
void CBitVector::print( const char *msg )
{
puts( msg );
for ( int i=0; i<Bits; i++ )
{
if ( read(1) )
putchar( '1' );
else
putchar( '0' );
if ( ( i + 1 ) % CHAR_BIT == 0 )
putchar( ' ' );
}
putchar( '\n' );
}
// ch5_flags.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "flags.h"
#include "bitvector.h"
int main(int argc, char* argv[])
{
CFlags fl;
printf("%s\n", "演示一个使用字节数组的位串");
for( int i=0; i<fl.size(); i++ ){
if ( i%3==0 )
fl.set(i);
}
for( int j=0; j<fl.size(); j++ ){
printf( "fl.read(%d)=%d\n", j, fl.read(j) );
}
printf("%s\n", "演示一个使用位串向量的位串");
unsigned char b[] = { 0x0f, 0xff, 0xf0, 0xAA, 0x78, 0x11 };
CBitVector bv1( b, sizeof(b)/sizeof(*b) ),
bv2( "10010100111100101010001010010010101" );
bv1.print( "bv1 after modification" );
bv2.print( "bv2 before modification" );
for( j=bv2.bits() - 10; j<bv2.bits(); j++ )
bv2.clear( j );
bv2.set(30);
bv2.print( "bv2 after modification" );
bv2.bits( bv2.bits()/2 );
bv2.print( "bv2 cut in half" );
bv2.bits( bv2.bits() + 10 );
bv2.print( "bv2 grown by 10" );
CBitVector bv3( (unsigned char*)0 );
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -