c++程序设计笔记(4)

来源:互联网 发布:大工软件学院 编辑:程序博客网 时间:2024/06/04 19:18
友元(Friend):
     友元函数和友元类
     友元函数:
     1、一个类的友元函数可以访问该类的私有成员
class A{
   int a;
public:
    A(int a1){
       = a1;
    }
friend void func(a);
};
void func(a){
    cout<<a.a<<endl;
}
int main() {
   a(2);
    func(a);
    return 0;
}
     2、一个类的成员函数(包括构造、析构函数)定义为另一个类的友元。访问非静态私有变量把A的对象作为形参
class B{  //A中要用到B的类型,所以要在之前对B进行声明。此处也体现出了.h和.cpp文件分离开的好处
public:
   void func();
};
class A{
   static int b;
   friend void B::func();
};
int A::b = 9;
void B::func(){
    cout<<A::b<<endl;
}
int main() {
   b;
    b.func();
    return 0;
}
     友元类:
          友元类不能传递!不能继承!
          A是B的友元类,B的成员函数可以访问A的私有成员(静态,非静态,非静态多加一个形参)
class A{
   static int b;
   friend class B;
};
int A::b = 9;
class B{
public:
   void func(){
        cout<<A::b<<endl;
    }
};
int main() {
   b;
    b.func();
    return 0;
}

this指针:
     指向成员函数所作用的对象。
     空指针也可以访问成员函数。
class {
   int a;
public:
   void func(){//编译时会多一个参数func(A* this)
        cout<<"come to A func"<<endl;
    }
   void func2(){
        cout<<"come to A func2:"<<this->a<<endl;

    }
};
int main() {
   *p = NULL;
    p->func();//可以调用
    p->func2();//运行错误
    return 0;
}
为什么空指针可以访问成员函数?知乎里有两个比较好的回答:
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:Damien
链接:http://www.zhihu.com/question/23260677/answer/33165965
来源:知乎

和c++内存布局有关,为了节约内存和提高调用效率,一般类成员的存储分成两块,一块是单个instance所有,比如非静态成员变量,另一块是所有instances共享的,比如函数代码。这样的布局是对于性能有好处的,代码只要load一次,减少了cache占用和miss。如果你的函数不引用任何instance独有的内存部分,nullptr并无问题,因为不会使用this,只会使用类instance共享的部分,这部分始终存在,即使你没有任何类实例。反之就会出问题,因为你试图访问不存在的数据

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:张景旺
链接:http://www.zhihu.com/question/23260677/answer/24081527
来源:知乎

但是对于C++。为了保证程序的运行时效率,C++的设计者认为凡是编译时能确定的事情,就不要拖到运行时再查找了。所以C++的编译器看到这句话会这么干:
1:查找somenull的类型,发现它有一个非虚的成员函数叫foo。(编译器干的)
2:找到了,在这里生成一个函数调用,直接调B::foo(somenull)。
所以到了运行时,由于foo()函数里面并没有任何需要解引用somenull指针的代码,所以真实情况下也不会引发segment fault。这里对成员函数的解析,和查找其对应的代码的工作都是在编译阶段完成而非运行时完成的,这就是所谓的静态绑定,也叫早绑定。
正确理解C++的静态绑定可以理解一些特殊情况下C++的行为。
0 0