C++ 默认成员函数、运算符重载 code

本文介绍了一个C++类的设计与实现细节,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载以及多种操作符如自增、比较等的重载方法。此外还展示了内存分配操作符new的重载过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

holy now


#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

class deffunc
{
private:
	struct item1
	{
		int a;
	};
	struct item2 {
		struct item1 a;
	};

public:
	/*
		typedef int * pintmy;
		const pintmy ci; // equal int *const ci;
		const int * cj;
	 */

	deffunc():b(2) {a = 1; e = (struct item2 *)malloc(sizeof(struct item2)); e->a.a = 5;};
	~deffunc();
	deffunc(const deffunc &obj);
	deffunc &operator =(const deffunc &obj);
	deffunc *operator &();
	const deffunc *operator &() const;
	/*
		it is a mistake like this:
		deffunc *operator &() const;
	*/
	
	/* operator new reload */
	void *operator new(size_t size, void *addr);
	void *operator new(size_t size, char *msg);
	void *operator new[](size_t size, char *msg);
	
	/* operator ++ reload */
	deffunc &operator ++() {a++; return *this;} // ++deffuncobj
	deffunc operator ++(int){deffunc tmp(*this); ++(*this); return tmp;} //deffuncobj--
	
	struct item1 &operator *() const {return e->a;}
	/* then written like this:
	      int &operator *() const {return test.a;}
	   is a big mistake:"const int can not be converted to int &" */
	struct item1 *operator ->() const {return &(e->a);}
	
	bool operator ==(const deffunc &obj) const {return a == obj.a;}
	
	deffunc& operator +=(const deffunc &obj)
	{
		a += obj.a;
		return *this;
	}
	
	deffunc operator +(const deffunc &obj)
	{
		deffunc tmp = *this;
		return tmp += obj;
	}
	
	bool operator ()(const deffunc &obj) {return a > obj.a;}
	
	
	void setmember(int val) {a = val;}
	void print() {printf("a=%d, b=%d, c=%d, d=%d\n", a, b, c ,d);}
	
private:
	int a;
	const int b;
	static int c;
	static const int d = 4;
	
	struct item2 *e;
	
	struct item2 test;

};

int deffunc::c = 3;

deffunc::~deffunc() {}

deffunc::deffunc(const deffunc &obj): b(obj.b)
{
	a = obj.a;
	e = (struct item2 *)malloc(sizeof(struct item2));
	e->a.a = obj.e->a.a;
}

deffunc &deffunc::operator =(const deffunc &obj)
{
	this->a = obj.a;
	return *this;
}

deffunc *deffunc::operator &()
{
	return this;
}

const deffunc *deffunc::operator &() const
{
	return this;
}

void *deffunc::operator new(size_t size, void *addr)
{
	return addr;
}

void *deffunc::operator new(size_t size, char *msg)
{
	printf("%s\n", msg);
	return ::operator new(size);
}

void *deffunc::operator new[](size_t size, char *msg)
{
	printf("%s\n", msg);
	return ::operator new(size);
}

int main()
{
	deffunc obj;
	obj.setmember(100);
	obj.print();
	
	deffunc obj1;
	obj1 = obj;
	obj1.print();
	printf("-1-------------1-\n\n");
	
	void *addr = malloc(sizeof(deffunc));
	deffunc *pobj = new(addr) deffunc;
	printf("pobj: %x, addr: %x\n", pobj, addr);
	pobj->print();
	free(addr);
	printf("-2-------------2-\n\n");
	
	deffunc *pobj1 = new("reload operator new") deffunc;
	pobj1->print();
	
	deffunc *pobj2 = new("reload operator new []") deffunc[20];
	pobj2[19].print();
	printf("-3-------------3-\n\n");
	
	obj.print();
	deffunc obj2 = ++obj;
	obj2.print();
	
	deffunc obj3 = obj2++;
	obj3.print();
	printf("obj3: %d\n", (*obj3).a);
	printf("obj3: %d\n", obj3->a);
	
	printf("-4-------------4-\n\n");
	obj2.print();
	obj3.print();
	printf("operator (): %d\n", obj2(obj3));
	
	printf("all will be OK\n");
}


<think>好的,我需要回答用户关于C++运算符重载的使用与示例的问题。首先,我需要回忆一下运算符重载的基本概念和相关规则。根据用户提供的引用内容,运算符重载允许用户自定义数据类型使用C++内置的运算符,比如关系运算符、算术运算符等。引文[^2]提到,重载运算符可以使操作更自然直观,这是关键点之一。 接下来,我应该确定回答的结构。用户希望了解如何实现和使用重载运算符,所以需要分步骤说明,可能包括基本语法、注意事项以及示例代码。根据引用[^3],C++编译器会为类生成默认的拷贝构造函数和赋值运算符,但用户可能需要自定义这些运算符。 我需要先解释运算符重载的基本语法,包括成员函数和友元函数两种方式。比如,重载+运算符作为成员函数时,参数数量比非成员少一个,因为隐含了this指针。同时,要注意不能创建新的运算符,只能重载已有的,并且不能改变运算符的优先级和结合性,这些是重要的注意事项,引文中有提到。 然后,给出几个常见的运算符重载示例。比如算术运算符+,关系运算符==,输入输出运算符>>和<<,以及赋值运算符=。每个示例需要展示代码,并解释其作用。比如,在Vector类中重载+运算符,实现向量相加;重载==来比较两个对象是否相等。引用[^1]提到关系运算符重载,可以用于比较类的对象,这需要体现在示例中。 另外,输入输出运算符通常需要重载为友元函数,因为它们的左操作数是流对象,而不是类的实例。引文[^2]中的示例部分应该包含这样的例子,所以需要确保代码正确,比如使用友元函数来重载<<和>>。 在注意事项部分,需要提到哪些运算符不能被重载,比如.和::,以及不能改变运算符的优先级。同时,要强调保持运算符的语义一致性,避免让+运算符执行减法的操作,这会让代码难以理解。 最后,生成相关问题,可能涉及运算符重载的应用场景、与内置类型的区别、深拷贝与浅拷贝的问题,以及如何实现特定运算符如自增或下标运算符。这些问题可以帮助用户进一步学习相关内容。 现在,我需要将这些内容组织成结构清晰的回答,使用用户要求的格式,确保所有数学表达式用$...$,独立公式用$$...$$,并正确引用提供的参考文献。同时,确保代码示例正确,符合C++语法,并解释每个示例的作用和结果。</think>### C++运算符重载使用与示例 #### 一、基本概念 运算符重载允许用户为自定义数据类型定义运算符的行为,使其像内置类型一样直观操作。例如,对`Vector`类重载`+`运算符实现向量加法: $$ \vec{v_1} + \vec{v_2} = (x_1+x_2, y_1+y_2) $$ #### 二、实现步骤 1. **语法形式** - **成员函数重载** ```cpp ReturnType operator运算符(参数) { ... } ``` - **全局函数重载(需声明为友元)** ```cpp friend ReturnType operator运算符(参数1, 参数2) { ... } ``` 2. **核心规则** - 只能重载C++已有的运算符(如`+`, `==`, `<<`),不能创建新符号 - 至少一个操作数为用户定义类型 - 不改变运算符的优先级和结合性 --- #### 三、常用示例 1. **算术运算符重载(`+`)** ```cpp class Vector { public: Vector operator+(const Vector& v) { return Vector(x + v.x, y + v.y); } private: double x, y; }; ``` - 使用:`Vector v3 = v1 + v2;` 2. **关系运算符重载(`==`)** ```cpp bool operator==(const Student& s1, const Student& s2) { return s1.id == s2.id; } ``` - 使用:`if (stu1 == stu2) ...` 3. **输入/输出运算符重载(`<<`, `>>`)** ```cpp friend ostream& operator<<(ostream& os, const Point& p) { os << "(" << p.x << "," << p.y << ")"; return os; } ``` - 使用:`cout << point;` 输出格式:`(3,5)` 4. **赋值运算符重载(`=`)** ```cpp Array& operator=(const Array& other) { if (this != &other) { // 防止自赋值 delete[] data; // 释放原有资源 data = new int[other.size]; size = other.size; std::copy(other.data, other.data + size, data); } return *this; } ``` - 必须返回引用以实现链式赋值:`a = b = c;` --- #### 四、注意事项 1. **不可重载运算符** `.`(成员访问符)、`::`(作用域解析符)、`?:`(条件运算符)等 2. **保持语义一致性** 重载运算符应保持原有含义(例如`+`不应实现减法逻辑) 3. **特殊运算符要求** - 赋值运算符`=`、下标运算符`[]`、函数调用运算符`()`必须定义为成员函数 - 流运算符`<<`/`>>`必须定义为友元全局函数 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值