)
友元友元函数friendfriend函数可以访问私有成员。#include iostream using namespace std; class Point { private: int x; int y; public: Point(int a 0, int b 0) : x(a), y(b) {} // 友元函数声明friend 写在最前面 friend Point operator(const Point p1, const Point p2); friend ostream operator(ostream os, const Point p); }; // 友元函数定义类外不加friend Point operator(const Point p1, const Point p2) { Point res; res.x p1.x p2.x; res.y p1.y p2.y; return res; } ostream operator(ostream os, const Point p) { os ( p.x , p.y ); return os; } int main() { Point p1(1,2); Point p2(3,4); Point p3 p1 p2; cout p3 endl; return 0; }一个问题我们在编辑上述两个代码时第二个函数在调用第一个函数的时候由于this指针具有常性直接调用会导致this指针权力的膨胀。如何解决这个问题我们可以通过这种方法来限制this指针的权力同时const修饰的是*this本质改变this的类型。这是硬性规定不是逻辑问题需要注意的是在使用const修饰符来限制this指针的时候该函数中赋值this指针的函数将不能正常使用。再谈构造函数初始化列表之前我们提过默认构造的两种条件1.完全没有参数class Myqueue { public: //无参数 Myqueue() { } }; Myqueue s;//可以正常使用2.有参数但全部参数都给了默认值class Myqueue { public: //有参但有默认值 Myqueue(int cap 10) { } }; Myqueue s;//可以正常使用但是当我们在写列表的时候有时会面临给参数但无法构成默认构造的情况。比如class Myqueue { public: //有参无默认值 Myqueue(int cap) { } }; Myqueue s;//不可以正常使用因为Myqueue有参数但是参数无默认值所以没有默认构造。我们也可以通过直接传值进行构造class Myqueue { public: Myqueue(int cap) { } }; int main(){ Myqueue q(10); return 0; }这样可以通过传参进行构造即初始化不是默认构造。但是当我们通过栈实现队列的时候typedef int DataType; class Stack { public: Stack(size_t capacity) { _array (DataType*)malloc(sizeof(DataType) * capacity); if (NULL _array) { perror(malloc申请空间失败!!!); return; } _capacity capacity; _size 0; } private: DataType* _array; size_t _capacity; size_t _size; }; class Myqueue { public: Myqueue(int cap) { } private Stack _pushst; Stack _popst; int _size; }; int main(){ Myqueue q(10); return 0; }此时我们仍旧可以通过传参来解决Myqueue的构造问题但是Myqueue中含有Stack自定义类型我们在调用Myqueue的时候也会调用Stack此时我们无法在给Myqueue传参的同时直接给Stack传参。但是我们可以直接初始化列表class Myqueue { public: Myqueue(int n 0) //初始化列表 :_pushst(n) ,_popst(n) ,_size(0) { } private Stack _pushst; Stack _popst; int _size; }; int main(){ Myqueue q(10); return 0; }冒号开始逗号分割。初始化列表可以理解为每个对象中成员定义的地方。class Myqueue { public: Myqueue(int n 0) //初始化列表 :_pushst(n) ,_popst(n) ,_size(0) _x(0) { //这里是函数体内部 } private Stack _pushst; Stack _popst; int _size; }; int main(){ Myqueue q(10); return 0; }——const类型、引用类型以及没有默认构造的自定义类型的成员必须在初始化列表初始化必须显式传参构造而不能在函数体内初始化。如果我们把Myqueue 中的成员初始化取消只在函数体内部声明会怎样class Myqueue { public: Myqueue(int n 0) //初始化列表 { //函数体内部 } private Stack _pushst; Stack _popst; int _size; }; int main(){ Myqueue q(10); return 0; }会发现初始化列表中的成员都会先走一遍初始化列表自定义类型会调用默认构造。实践中尽可能使用初始化列表不再方便使用函数体初始化。-成员变量在类中声明次序就是其在初始化列表中的初始化顺序与其在初始化列表中的先后次序无关。因为在这个类中a2声明比a1早所以在初始化列表中a2比a1先初始化。所以优先将没有初始化的a1赋值给a2致使a2为随机值而又将a赋值给a1。最后的输出结果为1和随机值。所以实战中尽量保持初始化列表与成员变量声明顺序一致。隐式类型转换const A raa 3;在这行代码中不存在拷贝构造因为3在传给A之前进行临时拷贝A直接作为该临时拷贝的别名。explicit函数该函数可以防止类进行类型转换。static