c++之说_9_6|自定义类型 struct operator 重载运算符关键字

c++中 struct  和 class  特性几乎一模一样

所以很多都是共有的特性 篇幅就很多了

c++中  我觉得最牛皮的概念之一 就是

重载运算符  operator 关键字

这个东西 能将  我们的  运算符 (+-*/) new  delete

 类型转换

写在类里面当成员函数 并制定 该类型变量运算时所适用的逻辑

以下是可重载的所有运算符:

e87c27d812124d0fb51764149ab5b02d.jpg

 这是重载运算符时的方式 注意  运算符替换掉 @

a3d662da964042a2b1ec2f1933d230df.jpg

 运算符 前缀后缀 放置位

ce19ef483ad8495285cb6213518a2bac.jpg

 限制 或 不可重载的符号

53b6a8863dcb4dc0bae42ebd328deed5.jpg


struct obj_3
{

	obj_3() {};
	obj_3(const int& Ina, const int& Inb) : a(Ina), b(Inb) {}


	int	geta()const { return a; };

	int	getb()const { return b; };


private:

	int a = 0;
	int b = 0;

};


struct obj_1
{

public:
	obj_1() { Ts = this;  };
	//使用了委托构造
	obj_1(const int& Ina, const int& Inb) : obj_1() { a = Ina; b = Inb; }


	int	geta() const { return a; };

	int	getb() const { return b; };
public:

	bool operator== (const obj_1& Target)
	{
		
		return  (this->a == Target.a) && (this->b == Target.b);
	};

	bool operator!= (const obj_1& Target)
	{

		return  !operator==(Target);
	};
	operator obj_3()
	{
		std::cout << __func__ << ":" << endl;
		return obj_3(99, 99);
	}

	void* operator new(std::size_t size, void* p, int io,char* c)
	{
		std::cout << "obj_1::" << __func__ << "(std::size_t size, void* p,char* c) :" << endl;
		std::cout << "operator new 构造的地址是:" << p << endl;
		std::cout << "operator new   io :" << io << endl;
		std::cout << "operator new   c :" << c << endl;
		return p;
	}

	void operator delete(void* p,size_t size, const char* c)
	{
		std::cout << "obj_1::" << __func__ << "(void* p,size_t size, const char* c) :" << endl;
		std::cout << "operator delete的地址是:" << p << endl;
		std::cout << "operator delete   size :" << size << endl;
		std::cout << "operator delete   c :" << c << endl;
		return;

	}


	int	operator[](int i)
	{
		std::cout << "obj_1::" << __func__ << "(int i) :" << endl;
		std::cout << "i = "<< i << endl;
		return a + i;
	}

	~obj_1() {};


private:

	obj_1* Ts;

	int a = 0;
	int b = 0;

};

struct obj_2
{

	obj_2() {};
	obj_2(const int& Ina, const int& Inb) : a(Ina), b(Inb) {}


	int	geta()const { return a; };

	int	getb()const { return b; };

	obj_2& operator= (const obj_1& Target)
	{

		std::cout << "obj_2::" << __func__ << "(const obj_1& Target) :" << endl;

		this->a = Target.geta();
		this->b = Target.getb();

		return *this;
	};

	operator obj_1()
	{

		std::cout << "obj_2::" << __func__ << ":" << endl;
		return	obj_1(this->a, 100);
	}


	~obj_2() {};


private:

	int a = 0;
	int b = 0;

};


int main()
{
	std::cout << __func__ <<":"<< endl;

	obj_1 a1(10, 1000);
	obj_2 b2(50, 10);
	obj_3 c3;
	obj_1 texta1;
	obj_2 textb2;


	std::cout << "初始化完各个对象的值" << endl;
	std::cout << "a1.a: "<<a1.geta() << endl;
	std::cout << "a1.b: " << a1.getb() << endl;
	std::cout << "b2.a: " << b2.geta() << endl;
	std::cout << "b2.b: " << b2.getb() << endl;
	std::cout << "c3.a: " << c3.geta() << endl;
	std::cout << "c3.b: " << c3.getb() << endl;
	std::cout << "texta1.a: " << texta1.geta() << endl;
	std::cout << "texta1.b: " << texta1.getb() << endl;
	std::cout << "textb2.a: " << textb2.geta() << endl;
	std::cout << "textb2.b: " << textb2.getb() << endl;

	textb2 =	a1;
	std::cout << "该操作完成时各个变量的值" << endl;
	std::cout << "a1.a: " << a1.geta() << endl;
	std::cout << "a1.b: " << a1.getb() << endl;
	
	std::cout << "textb2.a: " << textb2.geta() << endl;
	std::cout << "textb2.b: " << textb2.getb() << endl;
	
	texta1 = (obj_1)b2;
	std::cout << "该操作完成时各个变量的值" << endl;
	
	std::cout << "b2.a: " << b2.geta() << endl;
	std::cout << "b2.b: " << b2.getb() << endl;
	
	std::cout << "texta1.a: " << texta1.geta() << endl;
	std::cout << "texta1.b: " << texta1.getb() << endl;
	
	c3 = a1;
	std::cout << "该操作完成时各个变量的值" << endl;
	std::cout << "a1.a: " << a1.geta() << endl;
	std::cout << "a1.b: " << a1.getb() << endl;
	
	std::cout << "c3.a: " << c3.geta() << endl;
	std::cout << "c3.b: " << c3.getb() << endl;


	std::cout << "a1[100]: " << a1[100] << endl;


	static char b[10] = { 0 };
	char p = '2';

	obj_1* pobj1 = ::new obj_1;

	obj_1* pobjw = new(b, 9000,&p) obj_1;
	
	::delete pobj1;
	obj_1::operator delete( pobjw,60,&p);



	return  0;
}

部分测试代码我已放上

接下来我们运行看看

好 我们先看看第一处

textb2 =    a1;

textb2 是obj_2类型  a1 是obj_1类型

本来两个互不相同的自定义类型是无法使用 = 运算符的

但是此刻可以了 为何讷 

就因为运算符重载 operator

我们找到 obj_2 结构体是如何定义的

我们发现 有个 

obj_2& operator= (const obj_1& Target) 函数

其中有个输出函数 我们继续来看控制台

 obj_2::operator =(const obj_1& Target) :

证明  textb2 =    a1;

的确是运行了此函数

所以  obj_2& operator= (const obj_1& Target)

这个叫什么?

这个叫重载赋值符号

Target引用的值其实就是  a1

这是类中的写法

具体详细的大家去打断点试试

------------------------------------------------------------------------------

接下来看看这个

texta1 = (obj_1)b2;

texta1 是obj_1类型  b2 是obj_2类型

这语句一看 类型转换

但是细看  不对劲  不相关类型 如何支持转换

看了下控制台  输出了obj_2::operator struct obj_1:

我们去找找 obj_2里  输出的地方

operator obj_1()

这是什么?

这叫类型转换函数

obj_2 里面有个这个  证明了 有转换到 obj_1类型的方法

它返回了一个obj_1的临时对象  

我们看看a 和 b

  b2.a: 50
     b2.b: 10

  texta1.a: 50
     texta1.b: 100

构造的临时对象中的a使用了 b2.a , b使用了 100 

看了  没错是正确的

还是不太懂?

没事 继续看看 

    c3 = a1; 

 obj_3类型 c3    obj_1类型 a1;

这题一看 哎呦  我会 刚刚学过的  重载赋值运算符嘛!

一看输出  不对劲   operator struct obj_3:

怎么是类型转换函数呢?

去 obj_3类中看看

发现并没有operator 的函数

那就去obj_1类中看看

operator obj_3()

发现了obj_3 类型转换函数

所以这题运行的是类型转换函数

--------------------------------------------------------------------

接下来我们看

 a1[100]  

这个不是数组写法吗?

a1不是 obj_1类型的对象吗?

如何能当数组用  它又输出何物?

我们去看看obj_1类中怎么写的

我们发现了   int    operator[](int i)

看见了什么 operator 关键字  又是重载运算符

这次原来是重载数组运算符

返回的是 return a + i;

看了下 输出是 110 

之前a1.a 是多少?

-----------------------------------------------------------------

接下来我们来看看

void* operator new

重载 new 与 delete

直呼woc  c++ 还有什么运算符不能重载

void* operator new(std::size_t size, void* p, int io,char* c)

当然重载new 有一定的要求:

第一个形参必须是 size_t 类型的参数

看编译报错了

一般何时我们需要重载new呢?

要在指定的空间上进行创建对象时会进行重载

比如这里

我们看到了一个 
    obj_1* pobjw = new(b, 9000,&p) obj_1;

这写法很怪异

我们注意到了

b 是一个数组变量  证明是个地址

new(b, 9000,&p)  而语句是如此

我们去看看 重载位置 obj_1类中

看到了形参顺序 std::size_t size, void* p, int io,char* c

而调用是 new(b, 9000,&p) obj_1

有输出语句 我们去看看

我们发现 b= 00007FF6B74C0E90  io = 9000    c = ’2‘

顺序是按照  new(b, 9000,&p) obj_1

至于delete 要求是 第一个形参必须为  void *

还有一件事

可以加 virtual 关键字  也就是说可以成为虚函数  当然new 的例外  这个是 static 修饰的

我们可以看到虚表是被子类的 operator+(int c) 所覆盖了的 尽管她俩 返回值类型不同

浅谈结束

大家可以去该网站看看特性 语法规则

https://zh.cppreference.com/w/cpp/language/operators

  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在priority_queue中对自定义类型进行排序时,可以通过重载运算符来定义比较规则。比如,如果要按照元素值从大到小排序(小顶堆),可以在自定义类型的结构体或类中重载小于运算符(operator<)。例如,定义一个名为MyType的结构体,其中包含一个名为val的整数成员变量,可以重载小于运算符如下: struct MyType { int val; bool operator<(const MyType& other) const { return val > other.val; // 从大到小排序 } }; 然后可以使用以上自定义类型来定义一个priority_queue实例: priority_queue<MyType> pq; 这样,当向priority_queue中插入元素时,会按照自定义的比较规则进行排序。在上述例子中,元素会按照val的值从大到小排序。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [关于struct自定义类型的set/priority_queue重载运算符](https://blog.csdn.net/weixin_59534651/article/details/123141614)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [一文看懂priority_queue自定义比较函数有几种方法](https://blog.csdn.net/weixin_36389889/article/details/129802998)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [C++ sort / priority_queue自定义比较](https://blog.csdn.net/ahundredmile/article/details/126025258)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值