C++ Primer笔记(12) 类

来源:互联网 发布:linux查看网络配置 编辑:程序博客网 时间:2024/06/06 01:40

使用类型别名来简化类

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));

任何构造函数都可以用来显式地创建临时对象。