面面俱到----重载 (转)

本文介绍了C++中运算符重载的概念及其实现方法,包括如何为自定义类型实现加法运算符和如何定制输出操作。通过复数类的例子展示了重载运算符能显著提高代码的可读性和复用性。
面面俱到----重载 (转)[@more@]

面面俱到XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

  ----重载

作者:HolyFire

面面俱到说的是一件事考虑到了很多方面。有的时候我们的一句话适用于很多方面,而这些方面有些类似。比方说加法,加法可以用于,整数和有理数。在C++里可以用两个函数来实现这个目的。

int intadd( int v1 , int v2 )

{

  return  v1+v2;

}

float floatadd( float v1 , float v2 )

{

  return  v1+v2;

}

使用的方式是这样的

int ia = 1 , ib = 2 , iab = 0;

float fa = 1.0 , fb = 2.0 , fab = 0.0;

iab = intadd( ia ,ib );

fab = floatadd( fa , fb );

这样看起来很不直观,可读性不强,我们的目的是让人一眼就可以看出是在做相加运算。

聪明的读者可能发现,两个函数的返回值和参数并不一样,这样就可以区别开两个不同的行为。这个特性可不可以利用呢,答案是可以,C++贴心的为我们做好了一切。原理很简单,将函数的返回值和参数用一种可逆的编码方法变成一个字符串,安插在函数名后面,编译器用户屏蔽这一切,用户可以用同一个名字来使用不同的函数。

就是这样

int add( int v1 , int v2 )

{

  return  v1+v2;

}

float add( float v1 , float v2 )

{

  return  v1+v2;

}

int ia = 1 , ib = 2 , iab = 0;

float fa = 1.0 , fb = 2.0 , fab = 0.0;

iab = add( ia ,ib );

fab = add( fa , fb );

哦~~~~,编译通过了,结果也运行无误。

这样的代码看上去要比原来的好读多了,我们可以略过我们不感兴趣的那些东西。

重载的另一个方面是可以重载运算符,不同的是,它需要使用一个关键字operator。这样就可以用自己的方式来使用运算符了。那么立刻用运算符来改写上面的一切吧

int operator + ( int v1 , int v2 )

{

  return  v1+v2;

}

float operator + ( float v1 , float v2 )

{

  return  v1+v2;

}

int ia = 1 , ib = 2 , iab = 0;

float fa = 1.0 , fb = 2.0 , fab = 0.0;

iab = ia + ib ;

fab = fa + fb;

哦~~~,这段代码真是太漂亮了,可是不实用,为什么,用过C++的人都知道,象int,float这类的基本类型,本来就可以直接用运算符,那么,就来一个不是基本类型的吧。复数类在C++里可不是基本类型哦。

在这个例子里实现了complex类运算符+的重载,并重载了<

改变运算符原来的意义并不是一个好主意,应该尽量保证运算符原来的意义,我们使用它的本意就在于让程序易读易懂,书写方便,iostream中的<>是由于人们大量使用形成惯例后的产物,他们原来的意义是做移位运算。

#include

unsing namespace std;

class complex{

private:

  int real;

  int image;

public:

  complex( int _real = 0 , int _image = 0 ) : real(_real),image(_image) {}

  int& Real(){ return real; }

  int& Image(){ return image; }

  complex operator + ( complex const& v )

  {

    complex w( real + v.real , image + v.image );

    return w;

  }

};

ostream& operator << ( ostream& out , complex& v )

{

  if( v.Real() )

  out << v.Real() ;

  if( v.Image() > 0 )

  cout << " + " ;

  else if( v.Image() == 0 )

    return cout;

  else

  cout << " - " ;

  cout << v.Image() <

  return out;

}

void main()

{

  complex w( 1 , 2 ) , v( 3 , 4);

  cout << (w + v) << endl;

}

代码看起来很简洁,可读性很强。

我们可以看出<

使用重载的目的就是提高代码的可读性,运用得好还可以提高可复用程度。

2001/8/22

丁宁


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-990575/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-990575/

<think>首先,用户的问题是:“我想了解C语言面向过程编程和C++面向对象编程的差异”,这是一个明确的问题。 我的系统级指令包括: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,例如[^1]。 - 回答结构清晰,帮助用户逐步解决问题,保证真实可靠。 用户提供了几个引用,我需要参考它们来构建答案。这些引用讨论了面向对象编程(OOP)和面向过程编程(POP)的区别,以及C语言和C++的具体差异。 关键点从引用中提取: - 引用[1]:C语言是面向过程的,具体、面面俱到;面向对象是像正常人的思维。 - 引用[2]:C语言不是面向对象的,C++在C基础上添加了OOP功能。 - 引用[3]:C语言面向过程,数据和函数分开;C++面向对象,数据和函数一体化在类中,有权限控制(如public, private),支持继承、封装、多态。 - 引用[4]:C语言分析步骤实现,C++处理问题对象;提到函数重载- 引用[5]:示例用对象表示雨、人、伞来演示OOP。 用户的上一个问题似乎是关于这个主题,但在这个查询中,用户直接问差异,所以我需要基于这些引用构建一个清晰的回答。 回答结构: 1. **介绍概念**:简要解释面向过程和面向对象编程。 2. **核心差异**:对比C语言(POP)和C++(OOP)的关键区别。 3. **详细说明**:使用引用中的点来阐述。 4. **示例**:提供代码示例来阐明差异(如引用[5]的雨伞例子)。 5. **总结**:概括主要差异。 6. **生成相关问题**:在末尾添加相关问题。 确保使用中文回答。 代码部分:用户问题中没有明确要求代码,但引用中有示例(如引用[5]),我可以添加简单代码段来展示差异。指令说“尽量保证回答真实可靠”,所以包括代码是合适的。 数学表达式:用户问题可能不需要数学表达式,但如果涉及,需用正确格式。例如,如果有公式,但这里可能不直接相关。 引用标识:在回答中,当引用来源时,在段落末尾添加[^n]。 生成相关问题:在回答末尾,添加“§§相关问题§§”部分,列出几个相关问题。 完整回答结构: - 开头:直接回应问题。 - 主体: - 解释POP和OOP。 - 比较C和C++- 关键特性:封装、继承、多态(如引用[3])。 - 代码示例。 - 结尾:总结。 - 相关问题。 代码示例想法: - C语言POP示例:一个函数实现特定任务。 - C++ OOP示例:类定义和对象使用,如引用[5]的雨伞例子。 最终回答用中文。 </think> ### C语言面向过程编程与C++面向对象编程的差异 在计算机编程中,面向过程编程(POP)和面向对象编程(OOP)是两种不同的范式。C语言主要采用面向过程方式,而C++在C语言基础上扩展了面向对象特性。以下是两者的核心差异,基于引用内容逐步分析。 #### 1. **核心思想差异** - **面向过程编程(C语言)**: 以“过程”为中心,将问题分解为一个个具体的步骤(函数),然后按顺序执行这些函数。数据和函数是分离的:数据定义为变量,函数独立操作这些变量。这种方式要求程序员面面俱到地规划每个细节,类似于“按部就班地执行任务”。例如,在C语言中,你可能先定义变量,再在主函数中调用函数来实现逻辑。 ```c // C语言示例:计算两个数的和(面向过程) #include <stdio.h> int add(int a, int b) { // 独立函数 return a + b; } int main() { int num1 = 5, num2 = 3; // 独立变量 int sum = add(num1, num2); // 调用函数 printf("Sum: %d\n", sum); return 0; } ``` - **面向对象编程(C++)**: 以“对象”为中心,将数据和操作数据的方法封装在“类”中。对象是类的实例,代表现实世界中的实体。这种方式更接近人的思维方式,例如将“雨”“人”“伞”视为对象,每个对象有自己的属性和行为[^5]。C++通过类实现封装、继承和多态等特性,使代码更模块化和可重用[^3]。 #### 2. **关键特性对比** | 特性 | C语言(面向过程) | C++(面向对象) | |------|-------------------|-----------------| | **数据与函数的关系** | 数据和函数完全分离:变量独立定义,函数独立操作数据[^3]。 | 数据和函数一体化:通过类封装数据(成员变量)和方法(成员函数),并设置权限(如`public`、`private`)[^3]。 | | **代码复用** | 通过函数复用逻辑,但无结构化继承机制,复用性较低[^3]。 | 支持继承:子类可以继承父类的属性和方法,实现代码复用(如“富二代继承父辈财富”的比喻)[^3]。 | | **多态性** | 不支持多态:函数名必须唯一,无法根据参数不同实现不同功能[^4]。 | 支持多态:通过函数重载(同名函数不同参数)和虚函数实现同一接口的多种行为(如“打”动作可对应打羽毛球、打电话等)[^4]。 | | **问题解决方式** | 分析问题步骤,逐一实现函数(如先定义变量,再调用函数)。 | 以对象为单位设计:先定义类,再创建对象交互(如雨对象调用`fall()`,人对象调用`open()`)。 | #### 3. **代码示例对比** - **C++面向对象示例**:使用类封装数据和行为,并演示继承和多态。 ```cpp // C++示例:雨伞场景(面向对象) #include <iostream> using namespace std; class Umbrella { // 伞类 public: void open() { cout << "Umbrella opened!" << endl; } // 封装方法 }; class Person { // 人类 public: void open(Umbrella &umbrella) { umbrella.open(); } // 方法操作对象 }; class Rain { // 雨类 public: void fall() { cout << "Rain is falling!" << endl; } }; int main() { Rain rain; // 创建雨对象 Person person; // 创建人对象 Umbrella umbrella; // 创建伞对象 rain.fall(); // 对象交互 person.open(umbrella); return 0; } ``` 在这个例子中,每个对象(雨、人、伞)都有自己的行为,并通过类方法交互,体现了OOP的自然性。 #### 4. **实际影响** - **C语言的局限性**:C语言适合底层系统开发或简单任务,但随着项目规模增大,代码可能变得冗余和难以维护(“没有底线一处实现四处调用”)。 - **C++的优势**:C++在C语言基础上添加OOP特性,并优化了C的语法(如函数重载),提高了代码的灵活性、可扩展性和可读性[^2]。OOP更适合大型软件项目,因为它通过封装隐藏细节,通过继承减少重复代码。 #### 总结 C语言面向过程编程强调步骤分解和函数调用,适合小型或性能关键型应用;C++面向对象编程强调对象封装和类交互,更适合复杂系统的建模和扩展。两者并非互斥:C++兼容C语法,但OOP范式带来了更高的抽象层级,使编程更“像正常人的思维”[^3]。如果您有具体场景(如游戏开发或嵌入式系统),我可以进一步分析适用性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值