C++中构造函数的调用:
class Type
{
}
void main()
{
Type obj; //ok,编译器调用了默认的构造函数
Type obj1=Type(); //ok,显示调用了默认的构造函数
Type obj3(); //error ,其是声明了一个无参并返回Type类对象的函数obj
}
构造函数和析构函数都不参与继承。
this指针:
看一看编译器是怎样实现 this 指针的 为支持 this 指针,必须要应用两个转变
1 改变类成员函数的定义 用额外的参数 this 指针 来定义每个成员函数 例如
// 伪代码, 说明编译器对一个成员函数定义的展开形式
// 不是合法的 C++ 代码
inline void move( Screen* this, int r, int c )
{
if ( checkRange( r, c ) )
{
int row = (r-1) * this->_width;
this->_cursor = row + c - 1;
}
}
在这个成员函数定义中 显式使用 this 指针来访问类数据成员_width 和_cursor
2 改变每个类成员函数的调用 加上一个额外的实参——被调用对象的地址 例如
myScreen.move( 2, 2)
被转化为
move( &myScreen, 2, 2 )
静态类成员:
一般地 ,静态数据成员在该类定义之外被初始化 。如同一个成员函数被定义在类定义之外一样, 在这种定义中的静态成员的名字必须被其类名限定修饰 例如 下面是 interestRate
的初始化
// 静态类成员的显式初始化
#include "account.h" //存放Account类定义的地方
double Account::_interestRate = 0.0589;
与全局对象一样 对于静态数据成员 在程序中也只能提供一个定义 这意味着 静态数据成员的初始化(类似于成员函数在类外的定义)不应该被放在头文件中 而应该放在含有类的非 inline 函数定义的文件中
静态数据成员可以被声明为任意类型 它们可以是 const 对象 数组或类对象等等 例如
#include <string>
class Account {
// ...
private:
static const string name;
};
const string Account::name( "Savings Account" );
作为特例 有序型的 const 静态数据成员可以在类体中用一常量值初始化 例如 如果
决定用一个字符数组而不是 string 来存储账户的姓名 那么我们可以用 int 型的 const 数据成
员指定该数组的长度 例如
// 头文件
class Account {
// ...
private:
static const int nameSize = 16;
static const char name[nameSize];
};
// 文本文件
const int Account::nameSize; // 必需的成员定义
const char Account::name[nameSize] = "Savings Account";
关于这个特例 有一些有趣的事情值得注意 用常量值作初始化的有序类型的 const 静态数据成员是一个常量表达式 constant expression 如果需要在类体中使用这个被命名的
值 那么 类设计者可声明这样的静态数据成员 例如 因为 const 静态数据成员 nameSize是一个常量表达式 所以类的设计者可以用它来指定数组数据成员 name 的长度
在类体内初始化一个 const 静态数据成员时 该成员必须仍然要被定义在类定义之外 但是 因为这个静态数据成员的初始值是在类体中指定的 所以在类定义之外的定义不能指定初始值
因为 name 是一个数组 不是有序类型 所以它不能在类体内被初始化 任何试图这
么做的行为都会导致编译时刻错误 例如
class Account {
// ...
private:
static const int nameSize = 16; // ok: 有序类型
static const char name[nameSize] =
"Savings Account"; // 错误
};
name 必须在类定义之外被初始化
这个例子还说明了一点 我们注意到成员 nameSize 指定了数组 name 的长度 而数组 name
的定义出现在类定义之外
const char Account::name[nameSize] = "Savings Account";
nameSize 没有被类名 Account 限定修饰 尽管 nameSize 是私有成员 但是 name 的定义仍没有错 怎么会这样 如同类成员函数的定义可以引用类的私有成员一样 静态数据成员的定义也可以 静态数据成员 name 的定义是在它的类的域内 当限定修饰名 Account::name被看到之后 它就可以引用 Account 的私有数据成员