关于c++中的重载那些事儿

        c++中支持一种全新的特性,也就是重载。

        在c语言中,下面这种写法是不被允许的:

int sum(int, int);
double sum(double, double);

        上述代码的好处是显而易见的,干同一件事但是数据类型不同,如果能这样写无疑避免了函数名过多而造成的混乱,但是c语言明确写出:

        不允许函数名重复

        而c++作为c语言的升级版,则允许这种特性。虽然函数名称一样,但是它们的参数并不相同,而编译器在编译的时候,除了根据函数名编译以外,还会根据它所拥有的参数类型而来附加一些后缀,所以虽然函数名称相同,但却并不会给编译器带来歧义。值得注意的是,虽然可以根据其所拥有的参数类型来区分函数,但是这里所说的参数并不包括返回类型,也就是说仅仅依靠返回类型的不同,是无法重载函数的。至于原因,就在于编译器用参数给函数添加后缀是在编译函数名称之后,而返回类型的声明在函数名的前面,所以无法追加。

        对于后缀规则,不同的编译器拥有不同的规则,这里就不给出了。

        我们来做一些尝试:

class mine {
private:
	int a = 0, b = 0;
        double c = 0, d = 0;
public:
	void input(int, int);
        void input(double, double);
};

        首先,给出一个类的定义,可以看出,我声明了两个int型、两个double型变量,并且给出了相应的输入函数。

        注意:两个输入函数的名称相同,返回类型也相同,但是拥有不同类型的参数。

void mine::input(int a, int b) {
	this->a = a;
	this->b = b;
}
void mine::input(double a, double b){
        this->c = a;
        this->d - b;
}

        上述代码是两个函数的实现,可以看出两者代码基本一样,至于效果.......我在我的vs得出了预期中的结果,这就是重载大概的使用方式,而它能做的事比我刚才所介绍的还要多很多,来看下面的代码:

class mine {
private:
	int a = 0, b = 0;
public:
	mine operator +(const mine&);
	void input(int, int);
	friend ostream& operator << (ostream&, const mine&);
	
};

        <<操作符和+号相信都不陌生,而这里,我给出了两个函数它们,重载了这两个符号。╮(╯▽╰)╭有什么意义吗?

        当然有。我们之前用+号来把两个int、double、float类型的数据相加,很方便对吧?而且符合人类的习惯,但是这些符号,其实都是函数,对于基本数据类型的+号其实早就有人重载好了,我们只是相当于在调用函数而已。如果没有加号,而是用函数来写是什么样子呢?


        这就是大概的样子,Add函数就是+号重载的函数,看着脑壳痛,我们要追求原理,所以我选择重载+号╮(╯▽╰)╭。

mine mine::operator+(const mine& x) {
	mine t;
	t.a = a + x.a;
	t.b = b + x.b;
	return t;
}

        上述代码是+号的具体实现,这样+号就可以支持我自定义的结构体mine了。

        调用方式(以+号为例):

        o1.operator + (o2)

        o1 + o2

        上述两种调用方式等价的。

        不仅仅是+号,你所能想到的大部分符号都可以重载,因为它们的本质就是函数,比如-号,比如*号等等,还有我上面所给出的——   <<

         << 这两个尖角号有两个含义左移和流操作,而我重载的就是流操作,c++中输出就是cout了,标准库里重载了17个函数,当然,不可能有我们的自定义类,所以需要我们重载<< ,那么我们自定义的类也可以使用cout来进行输出了,下面给出实现:

ostream& operator << (ostream& out, const mine &x) {
	out << x.a << ' ' << x.b;
	return out;
}

        值得注意的是,这里的返回类型ostream& ,ostream被包含在头文件<ostream>里面,而这里的返回类型是对ostream的引用,所以才能流向cout,同理,我们也可以重载我们自定义类的输入:

istream& operator >>(istream& in, mine& x) {
	in >> x.a >> x.b;
	return in;
}

        但是如果你是在类中声明,那么只能使用友元的声明方式,原因是类的成员函数其实隐藏了一个this指针,但是输入输出流函数的这个指针被istream 和 ostream取代了,所以无法作为成员函数,但是可以通过友元的方式来对私有成员进行访问。

        还有一个比较有意思的就是c语言中的特殊运算符++了:

	mine& operator++();						//不带参数表示前缀++
	mine& operator++(int);						//带参数表示后缀++

        如上述代码注释所说的那样,重载++操作符的时候,如果带了一个参数(必须是int),那么编译器就认为是后缀++,虽然那个参数并没有发挥用处,使用时也不需要额外传入,仅作为一种区分方式,前缀++就没有参数。

mine& mine::operator++() {
	a++;
	b++;
	return *this;
}

mine& mine::operator++(int x) {
	++a;
	++b;
	return *this;
}
        照样给出代码实现,注意返回的是什么。

        大概就这么多了,如果发现有遗漏,我会补充的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值