温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

友元函数 运算符重载 const static

发布时间:2020-07-15 18:13:06 来源:网络 阅读:557 作者:汇天下豪杰 栏目:编程语言

1、友元函数

  在类中一般的成员函数具备:

  (1)、该函数能访问类中的私有部分

  (2)、该函数位于类的作用域之中

  (3)、该函数必须经由一个对象去激活,也就是说有一个this指针;

  友元函数不同之处:

  (1)、在#include<iostream> using namespace std;的前提下,必须的类外先声明;

class Test;
  void fun();    //有元函数的声明

  但是在#include<iostream.h>中不用这个有元函数的声明;这是早期头文件的包含。

  (2)、在类内必须声明是朋友,friend(关键字),函数声明

class Test{
  friend void fun();  //朋友没有公有,私有,保护之分,所以限定修饰符在这不起任何作用
};

(3)、在类外实现方法的定义,此时不用再加friend了;

void fun(){
  ..........
}

  有元函数具有的特性:该函数能访问类的私有数据;不是该类的成员函数,也不需要对象驱动;


友元函数 运算符重载 const static

  还有友元类,跟其使用一样,类中所有函数均可调用其朋友的私有数据;

2、运算符的重载(个人认为C++中运算符的重载很有用,也很重要)

  相当于函数的调用,对其的另一种更加人文化的解释,并告诉 C++编译器,遇到该重载运算符时调用此函数。

  定义运算符重载的一般格式:

  返回值类型 类名::operator重载的运算符(参数列表);

  假如出现复数类:

    Complex{
    public:
        .....
    private:
        int real;
        int p_w_picpath;
    };
    //主函数中:
    Complex t1(1, 2);
    Complex t2(2, 3);
    Complex t3;
    t3 = t1 + t2;

  此时t1和t2的类型不定,就得对+进行运算符的重载;使其更符合人文化,其本质不变,t1.operator+(t2);

  对象的类型不定,编译器不知道怎么输出,自己就得对<<和>>运算符进行重载,以达到输出对象的目的。还必须是友元函数;

class Complex;    //这是第一步,类外声明。
    ostream& operator<<(ostream &out, const Complex &c);
    istream& operator>>(istream &in, Complex &c);
    
class Complex{   //这是第二步,对其在类内说明是朋友。
    friend ostream& operator<<(ostream &out, const Complex &c);
    friend istream& operator>>(istream &in, Complex &c);
};
  
ostream& operator<<(ostream &out, const Complex &c){
    out<<"("<<c.m_real<<","<<c.m_imag<<")";
    return out;   //这是第三步,在类外进行定义。
}
istream& operator>>(istream &in, Complex &c){
    in>>c.m_real>>c.m_imag;
    return in;
}

关于这个<<对应一个要输出的值,在定义时,不用endl,回车。

对于Complate类的补充,t1 = t2 + 10;  //成员方法重载即可。内部有一个隐藏参数

     t1 = 10 + t2;  //没有对象驱动,还要10.operator+(t2);是错的,所以此时用友元函数,传两个参数就是有两个参数。

运算符的重载要注意:

  (1)、operator后面是一个合法的运算符,将右操作数做为函数的实参;

  (2)、++ --前后的问题,用函数重载区分,后加的(int)参数;

  (3)、?:  .   .*  ::  sizeof不能重载,其它的应该都可以进行重载;

例1:++i 和 i++有什么区别?

  对其进行重载,如下:

#include<iostream>
using namespace std;

class Int;
ostream& operator<<(ostream &out, const Int &s);

class Int{
    friend ostream& operator<<(ostream &out, const Int &s);
public:
    Int(int m = 0) : t(m){}
    ~Int(){}
public:
    Int& operator++()//++t  先加1,再将此对象的引用返回
    {
        t++;
        return *this;
    }
    Int operator++(int) //t++ 后加的要有一个参数int区分,
    {
        Int tmp(t);    //创建一个临时对象,
        t++;           //原有对象加了一下,
        return tmp;    //返回临时对象,后加。
    }
private:
    int t;
};

ostream& operator<<(ostream &out, const Int &s){
    out<<s.t;
    return out;
}
int main(void){
    Int t1(6);
    Int t2;
    Int t3;

    t2 = ++t1;
    cout<<"t1 = "<<t1<<", t2 = "<<t2<<endl;  //对输出运算符重载了,才能输出对象。
    t3 = t1++;
    cout<<"t1 = "<<t1<<", t3 = "<<t3<<endl;

    return 0;
}

运行结果如下:

友元函数 运算符重载 const static

  从结果可以看出,确是实现了,这块的本质是运算符对++的重载。

  前加,返回的是引用,后加还得调用构造函数和拷贝构造;所以前加++i;效率更高,运行速度也更快。

例2、String类

#include<iostream>
#include<string.h>
#include<assert.h>
using namespace std;

class String;
ostream& operator<<(ostream &out, const String &str);

class String{
    friend ostream& operator<<(ostream &out, const String &str);
public:
    String(const char *str = ""){
        if(str == NULL){
            data = new char[1];
            data[0] = 0;
        }else{
            data = new char[strlen(str) + 1];
            strcpy(data, str);
        }
    }
    //String(const String &str){}
    String& operator=(const String &str){
        if(this != &str){
            delete []data;
            data = new char[strlen(str.data) + 1];
            strcpy(data, str.data);
        }

        return *this;
    }
    ~String(){
        delete []data;
    }
public:
    String operator+(const String &str){
        char *tmp;

        tmp = new char[strlen(data) + strlen(str.data) + 1];
        strcpy(tmp, data);
        strcat(tmp, str.data);

        return String(tmp);
    }
    void operator+=(const String &str){
        char *new_data = new char[strlen(data) + strlen(str.data) + 1];
        strcpy(new_data, data);
        strcat(new_data, str.data);
        delete []data;
        data = new_data;
/*
        realloc(data, strlen(data) + strlen(str.data) + 1); //此时对原有的数组空间进行动态扩长,
             // 给谁扩长    加上原先,一共要有多长        即原有值不变。
        strcat(data, str.data);
*/
    }
    char operator[](int pos){
        assert(pos >= 0 && pos < strlen(data));
        return data[pos];
    }
    char operator*(){
        return data[0];
    }
    bool operator==(const String &str){
        return strcmp(data, str.data) ? false : true;
    }
    bool operator!=(const String &str){
        return !(*this == str);  //调用==这个编写过的函数
    }
private:
    char *data;
};

ostream& operator<<(ostream &out, const String &str){
    out<<str.data;
    return out;
}

int main(void){
    String s1("hello");
    String s2("world");
    String s3;

    s3 = s1 + s2;
    cout<<s3<<endl;
    s1 += s2;
    cout<<s1<<endl;
    cout<<s1[1]<<endl;
    cout<<*s1<<endl;
    if(s1 == s3){
        cout<<"相等"<<endl;
    }else{
        cout<<"不相等"<<endl;
    }
    if(s1 != s3){
        cout<<"不相等"<<endl;
    }else{
        cout<<"相等"<<endl;
    }
    return 0;
}

对其+,+=,[],*,==,!=进行了运算符的重载,结果如下:

友元函数 运算符重载 const static


3、const和static

  在C++中const是非常重要的,现在说明常函数之间的关系:普通函数可以调用常函数,常函数不能调用普通函数(因为没有this);

  void fun()const{}

  void fun(){}          //一个有const,一个没有,参数类型不一样,所以这是函数的重载!

  static在C++中有成员和方法,静态成员的在类外初始化;类的静态成员为所有对象所共享。

  静态方法: (1)、可以调用该类的私有成员,(2)、应该位于类的作用域之中;(3)、类名直接调用,可以不用方法;

  静态方法只能调用静态成员,和静态函数;非静态的可以调用静态成员或方法。



向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI