C++快速复习2

const修饰成员函数的几种情况:

1.const 在函数的最后,表示该成员函数不具有更改对象成员变量的权限;
class Stack
{
public:
void Push(int elem);
int Pop(void);
int GetCount(void) const; // const 成员函数
private:
int m_num;
int m_data[100];
 };
int Stack::GetCount(void) const
 {
++m_num; // 编译错误,企图修改数据成员m_num
Pop(); // 编译错误,企图调用非const 函数,
return m_num;
}
2.const放在函数返回值的前面的时候,是修饰返回值不能被修改,即函数的返回给的数据也必须是const的;

例如函数:

const char * GetString(void);

如下语句将出现编译错误:

char *str = GetString();

正确的用法是

const char *str = GetString();

需要说明的是:只要函数不修改对象的成员变量,就应该在函数定义之后加上const,这样的话,该函数既可以被const对象也可以被非const对象调用;
const对象只能调用const函数,而非const对象既可以调用const函数,也可以调用非const函数,在const函数中只能调用其他的const函数,即使被调用的函数不修改成员变量,const函数也不允许去调用非const函数

友元函数:

友元函数是一种打破对象的封装的函数,用friend关键字声明,而与声明的位置无关(无论在public还是private中都是一样的),友元函数的权限是被扩大,可以通过向友元函数传递对象来修改对象中的成员变量,

void ModfityA(myclass &a)
{
       a.a = 100;//正常来说,该函数是不具有修改a中成员变量的权限的,因为a是一个private的成员,但是在类的声明中一旦将该函数声明成类的友元函数,这句话将
//会被允许
}

在类中声明友元函数的格式:

class myclass
{
public:
       friend void ModfityA(myclass &a);//在类中将函数声明成为友元函数,则该函数具有修改对象中成员变量的权限,声明位置无关
private:
     int a;
     int b;
}

友元类:

像友元函数一样可以在类中任何位置声明;被声明为友元类的B可以随便的访问A中的私有成员变量,但是friend的方向是单向的,你是我的友元类,但是我不一定是你的友元类;
当类A将类B声明为友元函数的时候,B中的对象都具有访问A中的私有变量的权限

class myclass
{
public:
       friend class myclass1;//此处将myclass1类声明为这个类的友元类,
private:
     int a;
     int b;
}
class myclass1
{
public:
       void GetA(const myclass &a)//类myclass1中就可以访问A类对象的私有成员变量
       {
              cout << a.a << endl;
       }
};

运算符重载:

C++允许对操作符进行重载,操作符本质上可以看成是函数名称,,针对于类对象的操作的定义叫做运算符的重载,
重载的格式:

类型 类名::operator op(参数列表)

例如:friend myclass operator + (myclass C1,myclass C2);
两种实现方式:

class Complex
{
     public:
     private:
       int a;
       int b;//实部和虚部
}

针对于以上的类,在实现复数的加法运算的时候可以采用下列两种方式中的一种:

1.通过友元函数来实现:

通过在类中加入一个友元函数:
在类中的任何位置声明friend Complex operator +(const Complex&C1,Complex C2);

Complex operator +(const Complex& C1,Complex C2)

2.通过成员函数来实现:

由于成员函数本身是具有this指针的访问权的,所以运算符的参数会少一个;

Complex Complex::operator +(const Complex& C2);

而在调用该重载的操作符的时候:
可以使用诸如C3=C1+C2;
运算符重载的一些注意:
一些可以重载和不能重载的操作符:
不可重载的运算符

同时不能更改运算符的优先级,结合性,操作数,不能创造新的操作符;
一元操作符的重载例子:
前置++ 的实现:

1.成员函数法:

class myclass
{
public:
     myclass& operator ++()//通过成员函数实现前置++
       {
              this->a++;
              this->b++;
              return *this;
        }
private:
     int a;
     int b;
}

2.友元函数法:

class myclass
{
public:
       friend myclass operator ++(myclass & C1)//通过友元函数实现前置++
      {
              C1.a++;
              C1.b++;
              return C1;
       }
private:
     int a;
     int b;
}

后置++ 的实现:
1.成员函数法:

class myclass
{
public:
     myclass operator ++(int)//通过成员函数实现后置++
       {
              myclass tmp(*this);
              this->a++;
              this->b++;
              return tmp;
        }
private:
     int a;
     int b;
}

2.友元函数实现:

class myclass
{
public:
       friend myclass operator ++(myclass & C1,int)//通过友元函数实现后置++,与前置++ 参数列表上不同在于一个占位参数
       {
              myclass tmp(C1);
              C1.a++;
              C1.b++;
              return tmp;
       }
private:
     int a;
     int b;
}
对于输入输出流左移和右移运算符的重载:

由于左移和右移操作符的用在输入和输出的时候是属于iostream类对象中的重载的,所以如果想通过成员函数的方法使地<<和>>得到重载是不可能的,因此只能通过友元函数的方法来实现成重载:

重载<<

   friend ostream& operator<<(ostream& out, const myclass& C)
   {
          out << C.a << C.b << endl;
       return out;
 }
对于等号=的重载:

由于C++编译器默认是会提供给一个类似与浅拷贝的=赋值操作符,所以对于=的重载一般都是对含有指针的成员变量的更改:
错误存在的分析:简单的复制使得两个对象中的指针指向同一块内存中,这样在释放内存的时候会发生错误;
因此含有指针成员变量的=重载基本步骤是:
1.将旧指针的内容释放,2.根据新对象的长度申请新的内存空间3.完成对新的内存空间的拷贝
格式是:

myclass& operator=(const myclass& C)
{
       delete this->p;
       this->p = new char[10];
       for (int i = 0;i < 10;i++)
       {
              this->p[i] = C.p[i];
       }
         return C;//由于需要等号的连续赋值,在这里返回this指针和C对象是一样的
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值