您的位置:首页 > 编程语言 > C语言/C++

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

2016-08-10 21:48 211 查看

第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();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: