C++重载,重写和覆盖

本文详细介绍了C++中的重载、继承、虚函数、多态性和函数隐藏等面向对象特性,并通过具体代码示例解释了这些概念的区别及应用。

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

1.重载

重载构成的条件:函数的参数类型,参数个数不同。

#include <iostream>

class Point {
public:
	int x;
	int y;
	Point() {
		x = 0;
		y = 0;
	}
	Point(int a, int b) {
		x = a;
		y = b;
	}
};
Point pnt(5,5);

两个构造函数,参数个数不同。调用的函数取决于传值不同。在函数重载时,要注意函数中带有默认参数的这种情况。

2.继承

避免代码的冗余,C++实现了类的继承机制,父类称之为基类,子类也称之为派生类;

#include <iostream>

class Animal {
public:
	void eat() {
		cout << "animal eat" << endl;
	}
	void sleep() {
		cout << "animal sleep" << endl;
	}
	void breath() {
		cout << "animal breath" << endl;
	}
};

class Fish :public Animal {

};
void main() {
	Animal an;
	Fish fh;
	an.eat();
	fh.eat();
}

上述代码中,鱼子类继承自动物父类,拥有父类的吃、睡、呼吸函数。

构造fh对象时,animal类的构造函数首先被调用;析构时,最后析构父类。

3. 虚函数和多态性

#include <iostream>

class Animal {
public:
	void eat() {
		cout << "animal eat" << endl;
	}
	void sleep() {
		cout << "animal sleep" << endl;
	}
	virtual void breath() {
		cout << "animal breath" << endl;
	}
};

class Fish :public Animal {
	void breath() {
		cout << "fish breath" << endl;
	}
};
void main() {
	Animal an;
	Fish fh;
	an.eat();
	fh.eat();
}

在父类的函数名前加上virtual关键字,便构成了虚函数。这就是多态性,当C++编译器在编译的时候,发现父类的breath函数是虚函数时,采用迟邦定技术,也就是编译时并不确定具体调用的函数,而是在运行时,根据对象的类型来确认调用的是哪一个函数。

在派生类中重写该函数,如果运行时对象时派生类,就调用派生类的函数;如果是基类则调用基类的函数。

派生类和基类的某一函数,如果函数名,参数列表都一致,则是覆盖,或者叫做重写(override);构成覆盖的条件是:

1)基类函数必须是虚函数

2)发生覆盖的两个函数分别位于派生类和基类中

3)函数名称与参数列表完全一致

4.函数的隐藏

#include <iostream>

class Animal {
public:
	void eat() {
		cout << "animal eat" << endl;
	}
	void sleep() {
		cout << "animal sleep" << endl;
	}
	void breath() {
		cout << "animal breath" << endl;
	}
};

class Fish :public Animal {
	void breath() {
		cout << "fish breath" << endl;
	}
};
void main() {
	Animal an;
	Fish fh;
	an.eat();
	fh.eat();
}

派生类中的breath函数与基类的breath函数完全一样,不同的是基类函数不是虚函数,这种就称之为隐藏,也叫做重定义。

此时,要调用基类被隐藏的函数,可通过基类名::函数的形式。

5.例子

#include <iostream>
class Base
{
public:
	Base()
	{
		printf("I am Base()\n");
	}
	virtual ~Base()
	{
		printf("I am ~Base()\n");
	}
public:
	virtual void SayHello()
	{
		printf("Hello Base\n");
	}
	void SayWorld()
	{
		printf("World Base\n");
	}
};
class Derived : public Base
{
public:
	Derived()
	{
		printf("I am Derived()\n");
	}
	virtual ~Derived()
	{
		printf("I am ~Derived()\n");
	}
public:
	void SayHello();
	void SayWorld();
};

void Derived::SayHello()
{
	printf("Hello Derived\n");
}
void Derived::SayWorld()
{
	printf("World Derived\n");
}

int main(void)
{
	Base *b1 = new Base;
	Base *b2 = new Derived;
	Derived *d = new Derived;

	b1->SayHello();
	b1->SayWorld();

	b2->SayHello();
	b2->SayWorld();

	d->SayHello();
	d->SayWorld();

	delete d;
	delete b2;
	delete b1;

	d = NULL;
	b2 = NULL;
	b1 = NULL;
	while (1);

	return 0;
}

结果是:

I am Base()
I am Base()
I am Derived()
I am Base()
I am Derived()
Hello Base
World Base
Hello Derived
World Base
Hello Derived
World Derived
I am ~Derived()
I am ~Base()
I am ~Derived()
I am ~Base()
I am ~Base()

### C++重载重写覆盖的概念及区别 #### 1. 函数重载 (Function Overloading) 函数重载是指在同一个作用域内定义多个同名函数,但这些函数的参数列表(包括参数的个数、型或顺序)必须不同。返回值型的不同并不构成重载[^2]。例如: ```cpp class Example { public: void func(int a) {} // 参数为 int 型 void func(double a) {} // 参数为 double 型 void func(int a, int b) {} // 参数为两个 int 型 }; ``` - **特点**: - 必须在同一作用域内。 - 参数列表必须不同。 - 返回值型与重载无关。 #### 2. 函数重写 (Function Overriding) 函数重写是指在派生中重新定义基中的虚函数,要求函数名、参数列表返回值型相同。重写函数可以改变访问修饰符。例如: ```cpp class Base { public: virtual void func() {} // 基中的虚函数 }; class Derived : public Base { public: void func() override {} // 派生中的重写函数 }; ``` - **特点**: - 必须在派生中定义。 - 基函数必须是虚函数(`virtual`)。 - 参数列表返回值型必须一致。 - 访问修饰符可以不同。 #### 3. 函数覆盖 (Function Hiding) 函数覆盖是指派生中的函数隐藏了基中同名的函数。即使参数列表不同,基中的函数也会被隐藏。例如: ```cpp class Base { public: void func() {} // 基中的函数 }; class Derived : public Base { public: void func(int a) {} // 派生中的函数,隐藏了基的 func() }; ``` - **特点**: - 只要函数名相同,无论参数列表是否不同,基函数都会被隐藏。 - 使用作用域运算符(`::`)可以调用被隐藏的基函数。 #### 区别与联系 | 特性 | 函数重载 | 函数重写 | 函数覆盖 | |---------------------|--------------------------|--------------------------|--------------------------| | **作用域** | 同一作用域 | 基与派生之间 | 基与派生之间 | | **参数列表** | 必须不同 | 必须相同 | 不一定相同 | | **返回值型** | 无关 | 必须相同或协变 | 无关 | | **虚函数要求** | 不需要 | 基函数必须为虚函数 | 不需要 | | **访问修饰符** | 无关 | 可以不同 | 无关 | #### 示例代码 以下代码展示了重载重写覆盖的区别: ```cpp #include <iostream> using namespace std; class Base { public: virtual void func() { cout << "Base::func()" << endl; } // 虚函数 void func(int x) { cout << "Base::func(int)" << endl; } // 非虚函数 }; class Derived : public Base { public: void func() override { cout << "Derived::func()" << endl; } // 重写 void func(int x) { cout << "Derived::func(int)" << endl; } // 覆盖 void func(double x) { cout << "Derived::func(double)" << endl; } // 重载 }; int main() { Derived d; Base* b = &d; b->func(); // 调用 Derived::func()(重写) d.func(1); // 调用 Derived::func(int)(覆盖) d.func(1.0); // 调用 Derived::func(double)(重载) return 0; } ``` ### 输出结果 ``` Derived::func() Derived::func(int) Derived::func(double) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值