标签:参数表 析构 完全 mes type public 直接 friend 参数
一、特殊运算符的重载
1. 取值运算符:* "指针解引用运算符"
1)作用:让一个对象模拟指针的行为
2)重载方式:
<1>成员函数方式
class A
{
B & operator * (void) const {...}
};
<2>友元函数方式
class A
{
friend B & operator * (const A & rhs) {...}
};
#include <iostream>
using namespace std;
class B
{
public:
B(): b1(1), b2(2)
{
cout << "B()\n";
}
~B()
{
cout << "~B()\n";
}
public:
int b1;
int b2;
// int b[1000000]; //stack只有8M多,栈会放不下,必须new出内存存放
};
class AutoPtr
{
public:
AutoPtr(B *p): m_p(p) {}
~AutoPtr()
{
delete m_p; m_p = NULL;
}
B &operator *() const
{ //取值运算符 * 实现
return *m_p; //让*ap返回new出的一个B类型的对象
}
private:
B *m_p;
};
int main()
{
AutoPtr ap(new B);
cout << (*ap).b2 << endl;
/*B * pb = new B;
cout << "*(pb).b1 = " << (*pb).b1 << endl;
cout << "pb->b2 = " << pb->b2 << endl;
*/
return 0;
}
2. 取值运算符:->
1)作用:让一个对象模拟指针的行为
2)方式:
<1>成员函数方式
class A
{
B * operator -> () const {...}
};
#include <iostream>
using namespace std;
class B
{
public:
B(): b1(1), b2(2)
{
cout << "B()\n";
}
~B()
{
cout << "~B()\n";
}
public:
int b1;
int b2;
};
class AutoPtr
{
public:
AutoPtr(B *p): m_p(p) {}
~AutoPtr()
{
delete m_p;
m_p = NULL;
}
B & operator * () const
{
return *m_p;
}
B *operator -> () const
{ //取值运算符 -> 实现
return m_p;
}
private:
B *m_p;
};
int main()
{
AutoPtr ap(new B);
cout << (*ap).b1 << endl; //1
cout << ap->b2 << endl; //2
return 0;
}
3. 函数操作运算符: ()
如何重载()运算符 还是一样的三部曲 1.承认是函数 写出调用原型 f.operator()(3, 4); 2.根据原型 在类 F 中写出(函数名为operator()的)成员函数 3.使用重载后的运算符
1)作用:重载函数操作运算
2)方式:
<1>只能以成员函数方式重载
class A
{
返回类型 operator () (形参表) {...}
};
3)说明:
<1>只能以成员函数方式重载
<2>通常重载了"()"运算符的对象能像函数一样调用,我们把这样的对象叫做"函数对象",(lambda表达式的用法来源于函数对象),也叫仿函数
<3>该运算符中的形参表可以自定义("C++语言当中唯一一个参数表可变的运算符重载方式")
<4>该运算符中的形参可以有"默认实参"
<5>该运算符重载的成员函数的"返回类型也可自定义"
#include <iostream>
using namespace std;
class Sum
{
public:
Sum(): m_sum(0) {}
int operator () (int a, int b, int c = 0, int d = 0)
{
int s = a+b+c+d;
m_sum += s; //把每次调用的实参全部放在成员变量里做统计
return s;
}
int getTotal() const
{
return m_sum;
}
private:
int m_sum;
};
int main()
{
Sum s; //函数对象
int a = s(100, 200, 300, 400);
cout << "a = " << a << endl; //1000
a = s(500, 600);
cout << "a = " << a << endl; //1100
a = s(700, 800, 900);
cout << "a = " << a << endl; //2400
cout << s.getTotal() << endl; //4500
return 0;
}
4. 自定义类型转换运算符
1)作用:实现自定义的类型到其他类型(基础数据类型)的转换
2)方式:
<1>常成员函数方式
operator TYPE () const {}
<2>普通成员函数方式
operator TYPE () {}
3)说明:不能以友元函数方式重载。
#include <iostream>
using namespace std;
class Number
{
public:
Number(double a = 0): m_data(a) {}
operator int () const
{
return m_data;
}
public:
double m_data;
};
int main(void)
{
Number n1(100.222);
int i = n1; //类型转换,不重载类型转换运算符此处会报错
cout<<"n1.m_data= " << n1.m_data<< endl;
cout<<"i = " << i << endl;
cout<<"n1= "<<n1<<endl;
return 0;
}
5. new/delete 运算符重载
1)作用:特殊场合手动管理创建的内存和释放的内存
2)方式:
<1>只能以静态成员函数的方式重载
class A
{
static void * operator new (size_t size) { ... }
static void operator delete (void *p) { ... }
};
<2>只能以静态成员函数的方式重载 "new[]/delete[]"
class A
{
static void * operator new[] (size_t size) { ... }
static void operator delete[] (void *p) { ... }
};
3)说明:
<1>在重载 new/delete 时,不能使用 this 指针
<2>如果用户没有指定 static 编译器也会为其添加 static
#include <iostream>
#include <stdlib.h>
using namespace std;
class A
{
public:
//以下两个静态成员函数将在动态分配和释放单个对象时调用
static void * operator new (size_t size)
{
cout << "malloc(size): " << size << endl;
return malloc(size);
}
static void operator delete (void *p)
{
cout << "free(p): " << p << endl;
free(p);
p = NULL;
}
//以下两个静态成员函数将在动态创建和销毁数组时调用
static void * operator new[] (size_t size)
{
cout << "分配数组size = " << size << endl;
return malloc(size);
}
static void operator delete[] (void *p)
{
cout << "释放数组free(p): " << p << endl;
free(p);
p = NULL;
}
~A()
{
cout << "析构~~~" << endl;
}
private:
double m_d; //double 8 字节
};
int main()
{
//分配静态对象
A *pa = new A; //new 调用成员函数重载new
cout << "pa ------> " << pa << endl;
delete pa; //delete 调用成员函数重载delete
pa = NULL;
cout << endl;
//动态分配数组
pa = new A[2];
cout << "pa ------> " << pa << endl;
delete [] pa;
pa = NULL;
return 0;
}
【运算符重载小结】
1. 以下 6 个运算符不能重载:
1)作用域运算符 ::
2)直接成员访问运算符 .
3)成员指针解引用运算符 .*
4)条件运算符 ? :
5)字节长度运算符 sizeof
6)类型信息操作符 typeid (后续补充)
2. 以下 4 个只能以成员函数方式重载:
1)operator []
2)operator =
3)operator ->
4)operator ()
3. 运算符重载说明:
1)只能在原有的运算符上进行重载,不能增加运算符;
+++ //不可以!
2)运算符的重载不能改变运算符的优先级;
3)运算符重载无法改变运算符操作数的个数,"()"运算符除外;
4)完全是基础数据类型的运算符无法被重载;
补充:(成员指针解引用运算符)
1 成员变量指针 1)定义 类型 类名::*成员指针变量名 = &类名::成员变量; 2)使用 对象.*成员指针变量名; 对象指针->*成员指针变量名; ".*":成员指针解引用运算符 "->*":间接成员指针解引用运算符 注:成员变量指针的本质是类中特定成员在对象中的相对地址。
2 成员函数指针
虽然成员函数并不存储在对象中,但也要通过对象或者对象指针对成员函数指针解引用,其目的只有一个,即提供this指针 1)定义 返回类型 (*类名::成员函数指针)(形参表) = &类名::成员函数名; 2)使用 (对象.*成员函数指针)(实参表); (对象指针->*成员函数指针)(实参表);
#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;
class Student
{
public:
Student(const string & name = "",int age = 0):m_name(name),m_age(age){}
string m_name;
int m_age;
static int m_data;
static int add(int x , int y)
{
return x+y;
}
void who()
{
cout << m_name << " "
<< m_age << endl;
}
};
int Student::m_data = 100;
int _tmain(int argc, _TCHAR* argv[])
{//成员变量指针
string Student::*pname = &Student::m_name;//pname的初始化不需要对象,他将指向任何对象的m_name
//存成员变量的偏移量,在解引用时,使用起始位置+偏移量
int Student ::*page = &Student::m_age;
Student s1("张飞",24),s2("赵云",25);
//成员函数指针
void (Student::*pwho)(void) = &Student::who;
//成员指针时,取地址必须写
cout << s1.*pname << endl;//(.*,成员指针解引用运算符->*间接成员指针解引用运算符)
cout << s2.*pname <<endl;
cout << s1.*page << endl;
cout << s2.*page << endl;
(s1.*pwho)();
(s2.*pwho)();
int *pdata = &Student::m_data;
cout << *pdata << endl;
int(*padd)(int ,int ) = Student ::add;
cout << padd(100,200) << endl;
system("pause");
return 0;
}
标签:参数表 析构 完全 mes type public 直接 friend 参数
原文地址:https://www.cnblogs.com/tianzeng/p/9061736.html