pppploi8's Blog

欢迎来到pppploi8的个人博客!

C++ Primer学习笔记-隐式类类型转换和友元

隐式类类型转换

一言概之,就是在需要传递对象的时候传递符合构造函数的参数,C++会自动转换为对象

代码如下:

class ObjectA{
public:
    ObjectA(int a):ib(0.00){
        ia = a;
    } 
    ObjectA(double b):ia(0){
        ib = b;
    }
    void print(){
        cout << "a:" <<ia << endl << "b:" << ib <<endl;
    }
private:
    int ia; 
    double ib;
}; 
void printf(ObjectA o){
    o.print();
}
int main() {
    printf(123);
    printf(3.14);
    return 0;
}

另外,如果不希望自动转换,可以使用explicit关键字,如

explicit ObjectA(int a):ib(0.00){  }

那么 printf(123)则会调用到ObjectA(double a)构造函数,而不是ObjectA(int a)

如果需要的话也可以显式的调用构造函数,比如 printf(ObjectA(233));

在这种情况下,explicit关键字不会约束显式的调用构造函数,调用的则依然是ObjectA(int a)构造函数


友元

友元机制允许一个类将它非public成员的访问权限授予给制定的函数或类。

友元使用friend关键字

代码如下

class ObjectA{
    friend class ObjectB;//允许ObjectB类访问ObjectA类的私有数据 
private:
    int a; 
}; 
class ObjectB{
public:
    int getA(ObjectA& o){
        return o.a;
    }
    void setA(ObjectA& o,int s){
        o.a = s;
    } 
};
class ObjectC{
public:
    /*int getA(ObjectA o){
        return o.a;
    }*/
}; 
int main() {
    ObjectA oa;
    ObjectB ob;
    ObjectC oc;
    ob.setA(oa,123);
    cout << ob.getA(oa) << endl;
    //cout << oc.getA(oa) << endl;
    //注释部分因为没有ObjectA的访问权限,所以无法通过编译 
    return 0;
}

另外也可以只允许某个成员函数成为友元,而不是整个类,如下

class ObjectA;//声明类A,不然B类声明里会报错找不到ObjectA 
class ObjectB{
public:
    int getA(ObjectA&);
    void setA(ObjectA&,int); 
};//声明B类,必须在A类之前,否则报错找不到ObjectB  
class ObjectA{
    friend int ObjectB::getA(ObjectA&); 
    friend void ObjectB::setA(ObjectA&,int); 
private:
    int a; 
}; //具体实现,应当在类A定义后声明,否则会提示o里没有成员a 
int ObjectB::getA(ObjectA& o){
    return o.a;
} 
void ObjectB::setA(ObjectA& o,int i){
    o.a = i;
} 
int main() {
    ObjectA oa;
    ObjectB ob;
    ob.setA(oa,123);
    cout << ob.getA(oa) << endl;
    return 0;
}

另外,如果有重载函数的话,应该为每一个重载都设置为友元