使用类型别名来简化类
eg: class Screen{
public:
typedef std::string::size_type index;
private:
std::string contents;
index cursor;
index height,width;
};
成员函数可被重载
成员函数只能重载本类的其他成员函数。
eg: class Screen{
public:
typedef std::string::size_type index;
char get() const { return contents[cursor];}
char get(index ht,index wd) const;
private:
std::string contents;
index cursor;
index height,width;
};
Screen myscreen;
char ch = myscreen.get(); //calls Screen:get()
ch = myscreen.get(0,0); //calls Screen::get(index,index)
显示指定inline成员函数
可以在类定义体内部指定一个成员为inline,作为其声明的一部分。也可以在类定义体外部的函数定义上指定inline。在声明和定义处指定inline都是合法的。
eg: class Screen{
public:
typedef std::string::size_type index;
char get() const { return contents[cursor];}
inline char get(index ht,index wd) const;
index get_cursor() const;
private:
std::string contents;
index cursor;
index height,width;
};
char Screen::get(index r,index c) const
{
index row = r*width;
return contents[row+c];
}
inline Screen::index Screen::get_cursor() const
{
return cursor;
}
可以声明一个类而不定义它:
class Screen;
在创建类的对象之前,必须完整地定义该类。必须定义类,而不只是声明类,这样,编译器就会给类的对象预定相应的存储空间。同样,在使用引用或指针访问类的成员之前,必须已经定义类。
构造函数初始化
eg:Sales_item::Sales_item(const string &book):isbn(book),units_sold(0),revenue(0.0) { }
初始化const或引用类型数据成员的唯一机会是在构造函数初始化列表中。
eg,下面的构造函数是错误的:
class ConstRef {
public:
ConstRef(int ii);
private:
int i;
const int ci;
int &ri;
};
ConstRef::ConstRef(int ii)
{
i = ii; //ok
ci = ii; //error:cannot assign to a const
ri = i; //assigns to ri which was not bound to an object
}
编写该构造函数的正确方式为:
ConstRef::ConstRef(int ii):i(ii),ci(i),ri(ii) { }
初始化式可以是任意复杂的表达式。
eg:Sales_item(const std::string &book,int cnt, double price):isbn(book),units_sold(cnt),revenue(cnt * price) { }
内置和复合类型的成员,如指针和数组,只对定义在全局作用域中的对象才初始化。当对象定义在局部作用域中时,内置或复合类型的成员不进行初始化。
使有默认构造函数
如下声明是错误的:Sales_item myobj();
myobj的定义被编译器解释为一个函数的声明。
正确的是去掉括号:Sales_item myobj;
如下也是正确的:Sales_item myobj = Sales_item();
抑制由构造函数定义的隐式转换
将构造函数声明为explicit:
class Sales_item {
public:
explicit Sales_item(const std::string &book = ""):isbn(book),units_sold(0),revenue(0.0) { }
explicit Sales_item(std::istream &is);
};
explicit只能用于类内部的构造函数声明上。在类的定义体外部所做的定义上不再重复它。
现在,两个构造函数都不能用于隐式地创建对象。
item.same_isbn(null_book); //error:string constructor is explicit
item.same_isbn(cin); //error:istream constructor is explicit
当构造函数声明为explicit时,编译器将不使用它作为转换操作符。
为转换而显式地使用构造函数
eg:string null_book = "9-99-9999-9";
item.same_isbn(Sales_item(null_book));
任何构造函数都可以用来显式地创建临时对象。