c++运算符、继承、多继承中构造函数和析构函数顺序、内部类和局部类

一、自增自减运算符

单目运算符:正号(+) 负号(-) ++    --

开始代码:

#include <iostream>

using namespace std;
class point
{
private:
    int x;
    int y ;
public:
    int getX(){ return x;}
    void setX(int x) {  this->x = x;}

    int gety(){ return y;}
    void sety(int y) {  this->y = y;}
public:
    point(int x = 0 ,int y = 0);
    point operator=(const point& other);
    point operator+=(const point& other);
    int operator[](int x);
    void operator()(int a,int b);
// 前加加
   // point operator++();
   //后加加
  // point  operator++(int);
};
point::point(int x,int y)
:x(x),y(y)
{

}

全局函数实现方式(前++): student operator++(const stduent& other);

成员函数实现方式(前++):point point::operator++();

//前加加运算符
point operator++(point& other)
{

    other.setX(other.getX()+1);
    other.sety(other.gety()+1);
    return other;
}
//前++(成员函数)
point point::operator++()
{
    this->x++;
    this->y++;
    return *this;
}*

全局函数实现方式(后++): student operator++(const stduent& other,int);

成员函数实现方式(后++):point point::operator++(int );

   全局函数:

//后加加运算符
 point operator++(point& other,int)
 {
    point temp = other;
    other.setX(other.getX()+1);
    other.sety(other.gety()+1);
    return temp;
 }
//后加加实现(成员函数)
 point  point::operator++(int)
 {
        point temp = *this;
        this->x++;
        this->y++;
        return temp;
 }
 

注意:默认情况下,加加运算符是前加加,也就是++danny;

二、赋值运算符

格式1: void operator=(const person& other);

格式2: void operator+=(const person& ohter);

案例: 赋值运算符可以连续使用

   

//赋值运算符
point point::operator=(const point& other)
{
    this->x = other.x;
    this->y = other.y;
    return *this;
}

主函数的说明:

    point* px = new point(14,14);
    ++(*px);
    cout << "px->x"<< px->getX()<<endl;
    point ptemp = (*px)++; //拷贝构造
    point danny(1,2);
    ptemp = (*px);   //赋值运算符 x=y=z;
    cout << "px->x"<< ptemp.getX()<<endl;
    danny =  ptemp = (*px);
    cout << "danny.x" << danny.getX()<<endl;

注意:赋值运算符只可以是成员函数实现方式,不可以是全局函数和友元函数

      如果没有手动添加赋值运算符,编译器会自动添加缺省赋值运算符。

    

三、下标运算符

   格式: int  operator[](int x)

   案例:

       

//下标运算符  
 int point::operator[](int x)
 {
    if(x >= 2 || x < 0)   {        return y;    }
    else if( x == 1)    {        return y;    }
    else    {        return x;    }
 } 

       主函数调用:

    cout << "px->x"<< ptemp.getX()<<endl;
    danny =  ptemp = (*px);
    cout << "danny.x" << danny.getX()<<endl;
    cout << "danny[1]" << danny[1] <<endl;

   注意:只可以是成员函数实现

四.流运算符  

     定义:在使用cout或者cin的时候,会用到<< 和 >>运算符,这就是流运算符

     对象: cout是输出对象,已经定义好的,是ostream类型对象

            cin是输入对象,已经定义好的,是istream的类型对象

     格式1: ostream& operator<<(ostream& out,student& other);  输出流

     格式2: istream& operator>>(istream& in,point& other)     输入流

     注意: 只可以是全局函数实现流操作符,不可以是成员函数和友元函数

     案例:

       

ostream& operator<<(ostream& out,point& other)
{
    out << "x="<<other.getX()<<" y = "<<other.gety()<<endl;
    return out;
}
istream& operator>>(istream& in,point& other)
{
    int x=0;
    int y=0;
    in>>x>>y;
    other.setX(x);
    other.sety(y);
  
    return in;
}

       

五、小括号运算符

   定义:函数调用运算符重载,有时候希望对象有像函数一样的使用方式,

         也称之为仿函数,没有固定的写法,比较灵活;

格式: 返回值  operator()(参数){}

调用:  对象(参数);

案例:

    

//函数调用运算符   括号运算符
void point::operator()(int a,int b)
{
    cout << "a ="<<a << "b =" << b <<endl;
}   

调用:danny(1,2);  ----以这种方式进行调用    

六、继承

1.为什么要继承

   面向对象啊设计中非常重要的概念是继承,继承允许使用另外一个类来定义新类

   达到了代码重用的作用和提高执行效率

   提高了开发效率,不需要重新写父类有的成员函数和方法。

1)概念

  父类:也叫基类,例如动物类派生出基类,动物类是基类,

  子类:也叫派生类,例如动物类派生出鸡类,鸡类是子类;

  关系: 基类是已经有的类,派生类是继承了父类产生的新类

2)格式: class 子类: 继承控制 父类{  };

3)继承控制: public  private  protected三种,使用最多的是public     

 public继承:父类中的共有成员,子类继承后还是公有

             父类中的私有成员,子类继承后不可以使用;等价于没继承

             父类中的保护成员,子类继承后还是保护成员;

 private继承:将父类的属性在子类中修改成私有,父类私有子类无法访问;

 protected继承:将父类的属性在子类中修改成保护,父类私有子类无法访问;

4)子类无法继承

   A: 父类的构造函数,析构函数,拷贝构造没法继承

   B: 父类的友元函数和友元类没法继承

   C: 父类中的重载的运算符没法继承

5)继承的构造顺序

  A: 先构造父类,再构造子类,父类的构造在子类的构造函数初始化列表中调用;

  B: 先析构子类对象,再析构父类对象;

  C:所有的子类在初始化列表中都会调用父类的构造函数;

      如果子类构造没有主动添加父类构造,编译器自动调用父类的缺省构造函数;

   D: 子类复制了所有父类的成员变量和方法,父子类之间是不同的内存空间;

   E: 如果子类定义了父类的相同方法或变量,则隐藏了父类的方法和变量,优先使用子类

七、多继承

1.定义: 一个子类继承了多个父类,具有多个父类的方法和属性

2.格式:class 子类:public 父类1 , public 父类2{};      

3)多继承中构造函数和析构函数顺序

  构造顺序:父类是先继承先构造,后继承后构造,构造完父类后构造子类

  例如: class  pandan:public  cat,public bear

         上例子中:先构造cat,再构造bear ,然后构造pandan

  析构顺序:先析构子类,再调用后继承的类,再析构先继承的类

  例如: class  pandan:public  cat,public bear

          上例子:先析构pandan,再析构 bear 再析构cat (入栈和出栈的过程)

3.菱形继承(需要避免)

一个父类产生两个子类,然后两个子类继续产生孙子类,在孙子类中有多个爷爷变量

        (虚继承解决菱形继承的问题)

八、内部类和局部类

1.内部类:定义在类中的类;

         如果将类A定义在类B中,那么A是B的内部类(类嵌套)

2.特点

       内部类支持public private protected属性限制;

       内部类中的成员函数可以直接访问外部类的所有成员函数(反过来不行)

       内部类可以访问static的成员变量

       内部类不会影响外部类的内存;

       内部类可以在外部类中申明,在外部实现(申明和实现可以分开)

3.局部类:定义在函数内部的类;

  4.局部类的特点:

     作用域在函数内部,只可以在函数内部使用,在外部没法定义对象

     所有的成员必须定义在类的内部,不允许定义static变量

     局部类不可以访问函数中的局部变量;

5.匿名对象

      定义:没有变量名,没有被指针指向的对象,用完后立马调用析构释放;

            匿名对象使用不会和引用关联;

      Class Box{ public: Box(int x = 0){} }  ;   Box fun() {   return Box(1);  }

6.构造函数相互调用

      为什么用: 构造函数可以有参数,使得代码量大,可在构造中调用自己的其他构造;

                考虑长期问题,代码修改的内容比较小,一个构造修改,其他全部修改;

     实现方式:在子类的构造函数初始化列表中调用父类的构造函数;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值