C++PRimer
inline
调用函数不但必须拷贝两个实参保存机器的寄存器程序还必须转向一个新位置。
将在程序中每个调用点上被内联地 展开
函数声明或定义中的函数返回类型前加上关键字 inline
把 inline 函数的定义放到头文件中在每个调用该 inline
函数的文件中包含该头文件
函数原型
函数声明由函数返回类型函数名和参数表构成这三个元素被称为函数声明 function
declaration 或函数原型 functionprototype
缺省实参
char *screenInit( int height = 24, intwidth = 80,
char background = ' ' );
// 等价于 screenInit(24,80,' ')
cursor = screenInit();
// 等价于 screenInit(66,88, ' ')
cursor = screenInit(66);
指向函数的指针
int gcd( int, int ){
return 44;
}
int (*pf)( int, int );
int main()
{
pf=gcd;
cout <<pf(2,3) << endl;
函数指针的数组
pf=gcd;
extern
externint i;(extern 只声明不定义,去掉会造成重复定义)
externint i;(可以重复声明。)
extern int i ;(全局变量为0;extern可加可不加)
inti ;(error,重复定义)
intmain()
{
cout<<i << endl;
extern对于函数,同上。
局部对象
局部变量的生命期局限于所在函数的每次执行期间。
自动对象
为初始化的内置类型局部变量,其初值不确定。
当函数调用结束时,自动对象就会撤销。
形参也是自动对象。
一个变量如果位于函数的作用域内,但生命期跨越了这个函数的多次调用,这种变量往往很有用。应该将这样的对象对象定义为static。 static局部对象确保不迟于在程序执行流程第一次经过该对象的定义语句时进行初始化。这种对象一旦被创建,在程序结束前都不会撤销。
函数调用:调用前先保存寄存器,并在返回时恢复;
auto_ptr
用来释放数组的 delete 表达式形式如下
delete[] str1;
constint *pci = new const int(1024);
deletepci;
名字空间定义
namespacecplusplus_primer {
class matrix { /* ... */ };
void inverse ( matrix & );
constdouble pi = 3.1416;
}
void cplusplus_primer::inverse ( matrix &m){}
void func( cplusplus_primer::matrix &m )
{cplusplus_primer::inverse(m);}
cplusplus_primer::matrix m;
func(m );
名字空间的定义可以非连续
namespacecplusplus_primer {}
if( cur > ::max ) break;
嵌套域
cplusplus_primer::MatrixLib::matrix
隐藏
隐藏 ::Type
隐藏 MatrixLib::val
未命名的名字空间
namespace {
void swap2( double d1, double d2 ) { /* ... */}
}
swap2(3,4);
未命名名字空间成员名只在特定的文件中可见 在构成程序的其他文件中是不可
见的
// 短别名
namespace mlib2 = cplusplus_primer::MatrixLib;
namespace mlib=mlib2;
// 较易读
void func( mlib::matrix &m )
{
cout << mlib::pi<< endl;
}
mlib::matrix m22;
func( m22 );
using cplusplus_primer::MatrixLib::matrix;
matrix m22;
func( m22 );
using cplusplus_primer::MatrixLib::matrix;=using namespacecplusplus_primer::MatrixLib;
.
ostream& Operator<< ( ostream&o, const Screen& s ){
cout << s.addToken()<< endl;
}
int addToken( )const ;
这些函数被自动作为 inline 函数处理
把成员函数声明为 const 以表明它们不修改类对象
只有被声明为 const 的成员函数才能被一个 const 类对象调用
把一个修改类数据成员的函数声明为 const 是非法的
构造函数和析构函数不是 const 成员函数 const类对象也可以调用它们
当构造函数执行结束 类对象已经被初始化时 类对象的常量性就
被建立起来了 析构函数一被调用 常量性就消失 所以一个 const 类对象 从构造完成时
刻到析构开始时刻 这段时间内被认为是 const
Account myAcct( "Tinkerbell");
Tinkerbell 被转换成一个临时的 string 对象 然后该对象冉被传递给一个双参数的构
造函数 它的第一个参数是 string 类型
对于我们的新 string 类类型不够用 例如如下代码将失败
string new_client( "SteveHall" );
Account new_acct( new_client, 25000 );
因为在从 string 对象到 char*之间没有隐式转换 而写成
成员初始化表跟在构造函数的原型后 由冒号开头
如果成员是类对象 则初始值变成被传递给适当的构造函数的实参 该构造函数然后被应用在成员类对象上
在我们的例子中 name 被传递给
应用在_name 上的 string 构造函数 _balance 用参数 opening_bal 初始化
Account( const Account &rhs )
{
_name = rhs._name;
在隐式初始化阶段调用了缺省的 string 构造函数 并且在构造函数体内调用了
string 拷贝赋值操作符
成员初始化表:将成员的初始化和赋值分开。
缺省的按成员赋值 default memberwiseassignment 所处理的是 用一个类对象向该类
的另一个对象的赋值操作
利用了一个隐式的拷贝赋值操作符来取代拷贝构造函数
可能会生成一个缺省构造函数 但是它不会为内置或复
合型的数据成员 如指针或数组 提供初始值
拷贝构造函数 inline Account::Account( const Accout&rhs )
用一个类对象初始化该类的另一个对象被称为缺省按成员初始化
一个类对象向该类的另一个对象作拷贝是通过依次拷贝每个非静态数据成员来实现的
按成员赋值inline Account&Account::operator=(const Account &rhs )
一般来说 如果缺省的按成员初始化对于一个类不合适 则缺省的按成员赋值也不合适
新闻热点
疑难解答
图片精选