C++primer plus 第11-12章笔记

来源:互联网 发布:天津大学网络教学 编辑:程序博客网 时间:2024/06/05 11:45

第11章

  • 运算符重载:
    举例:
Time Time::operator+(const Time & t) const{    Time sum;    sum.minutes = minutes + t.minutes;    sum.hours = hours + t.hours + sum.minutes / 60;    sum.minutes %= 60;    return sum;}

可以通过函数调用,也可以通过运算符调用。其他运算符重载类似。

  • 友元:
    即让非成员函数能够访问私有数据。
    创建过程:
    1.在类声明中,用friend修饰:friend Time operator*(double m);
    2.不需要用类限定符限定方法,也不需要friend修饰,在类外编写函数定义:Time operator*(double m){}

  • 类的转换

Stonewt::Stonewt(double lbs){    stone = int (lbs) / Lbs_per_stn;    // integer division    pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs);    pounds = lbs;}

Stonewt类如果有上面的构造函数时,在遇到如下代码的时候会发生自动类型转换:

Stonewt myCat;myCat = 19.3;

会将double类型转换为Stonewt类型。
自动转换发送的情况:(在转换没有二义性的时候才进行)
- 将Stonewt对象初始化为double值时;
- double值赋给Stonewt对象时;
- double值传递时接受Stonewt参数;
- 返回值为Stonewt的函数返回double值时。
如果不希望这种自动类型转换可以在类声明中添加关键字explicit,即explicit Stonewt(double lbs)。

  • 如果想把Stonewt转换成double类型,就需要转换函数:
    创建过程:
    1.在类声明中,operator double();
    2.在实现中,Stonewt::operator double(){ return pounds; }
    其实就是自定义强制转换:像下面这样调用。
Stonewt wolfe(2.3);double host = double (wolfe);double host = (double) wolfe;double host = wolfe;

注意在输出cout中时关注这种转换的二义性。具体看书420页的例子。

第12章

  • 不能再类声明中初始化静态成员变量,因为声明只是描述,不分配内存。另外初始化是在方法文件中,不是在类声明文件中,否则会出现多次初始化。

  • 把类对象当作函数参数使用会在函数结束的时候调用析构函数。
    用一个对象初始化另外一个对象时,编译器会生成复制构造函数。

  • 默认构造函数:
    Klunk::Klunk(){}
    没有参数,在没有匹配的构造函数时自动调用,可以设置某些特定的值。

  • 复制构造函数
    在一个新对象用旧对象初始化的时候调用。
    格式:Class_name(const Class_name &)
    默认的复制构造函数逐个复制非静态成员,复制的是成员的值,是浅复制。这种复制很容易出错,在析构函数被调用的时候,很容易重复释放同一块内存。
    可以通过深度负责来解决,复制一个副本,并把副本的地址给新对象,而不是像浅复制仅仅负责地址而已。
    例如:

String::String(const String & st){    num_strings++;             // handle static member update    len = st.len;              // same length    str = new char [len + 1];  // allot space    std::strcpy(str, st.str);  // copy string to new location}
  • 赋值运算符的重载中和复制构造函数一样,应该避免浅复制,使用深度复制:
String & String::operator=(const String & st){    if (this == &st)        return *this;    delete [] str;    len = st.len;    str = new char[len + 1];    std::strcpy(str, st.str);    return *this;}
  • 静态成员函数是属于类的,所以不可以通过类对象来调用。同样,静态成员函数也不会使用特定的对象的值,只会使用静态数据成员。

  • 返回的说明:

    • 返回指向const对象的引用:
      返回引用不会调用复制构造函数。
    • 返回指向非const对象的引用:
      返回对象或对象的应用都可以。但是像ostream没有公用的复制构造函数,则只能返回引用。
    • 返回对象:
      返回对象不能接受引用。
    • 返回const对象:
      返回的对象不能被修改。
  • 对象指针
    String * first;
    可以用->访问类方法。

  • 定位new运算符和之前一样,不会考虑内存是否已经被用过了,且不能用delete [] buffer释放内存,因为存储位置不再堆内。只能通过显式地使用定位new运算符创建的对象调用析构函数。例如:

pc3 = new (buffer) JustTesting(6);pc3->~JustTesting();
0 0