不同编程范例中的表现形式
注:由于C 同时支持下面要提到的三种编程范例(Programming Paradigm) ,所以就用C 语言为例来说明
C 中对静多态的支持方式有:全局函数重载和运算符重载。
全局函数重载代码:
一下代码中均不考虑函数的返回类型,因为C 中不允许只有函数类型不同的重载。
1)参数个数不同而参数类型相同(对应位置):
void defParamNum(int paramFst);
void defParamNum(int paramFst, double paramSec);
2)参数个数相同而参数类型不同:
void defParamType (int paramFst, double paramSec);
void defParamType (double paramFst, int paramSec);
3)参数个数和参数类型都不相同:
void defBoth(int paramFst);
void defBoth(double paramFst, int paramSec);
运算符重载代码:
其实运算符重载也是一种函数重载。其中多了一些限制,比如一元运算符、二元运算符所要求的参数个数,还有运算符重载的元型(Prototype)都有明确的规定,再就是一些像C语言等不支持运算符重载,所以这里单独列出来。
一元运算符重载:(负值运算符 operator -)
Complex operator – (const Complex& elem)
{
// 复数temp的值为0 0i
Complex temp;
// 将temp的实部设为elem实部负数
temp.setReal(-elem.getReal());
// 将temp的虚部设为elem虚部的负数
temp.setImage(-elem.getImage());
// 返回temp复数,此时temp就是elem对应的负数了
return temp;
}
二元运算符重载:(加法运算符 operator )
Complex operator (const Complex& lhs, const Complex& rhs)
{
// 复数temp的值为0 0i
Complex temp;
// 将temp的实部设为lhs和rhs实部的和
temp.setReal(lsh.getReal() rhs.getReal());
// 将temp的虚部设为lhs和rhs虚部的和
temp.setImage(lsh.getImage() rhs.getImage());
// 返回temp复数,此时的temp就是lhs和rhs的和
return temp;
}
其实面向对象编程(Object-Oriented Programming)中也表现为函数重载和运算符重载。
函数重载:成员函数重载,静态成员函数(static)重载,虚函数重载,友元函数重载。
class Complex {
public:
// 构造函数重载:
Complex() : m_real(0), m_image(0) { };
Complex(double real, double image) : m_real(real), m_image(image) { };
// 静态成员函数重载:不恰当的例子
staticvoid staticFunc()
{
std::cout << "staticFunc()" << std::endl;
}
staticvoid staticFunc(int oneParam)
{
std::cout << "staticFunc(int oneParam)" << std::endl;
}
// 虚函数重载:不恰当的例子
virtualvoid virtualFunc()
{
std::cout << "virtualFunc()" << std::endl;
}
virtualvoid virtualFunc(int oneParam)
{
std::cout << "virtualFunc(int oneParam)" << std::endl;
}
// 虚函数重载:不恰当的例子。其友元函数就是一般的全局函数
friendvoid friendFunc();
friendvoid friendFunc(int oneParam);
// 运算符重载:Comple Comple
// Complex Complex成员版本:允许一个complex对象和另一个Complex对象相加
Complex operator (const Complex& elem)
{
return Complex(m_real elem.m_real, m_image elem.m_image);
}
// Complex double成员版本:允许一个complex对象和另一个double对象相加
// 只能是Complex double,不能是double Complex
Complex operator (double elem)
{
return Complex(m_real elem, m_image);
}
// Complex Complex友元版本:允许一个complex对象和另一个Complex对象相加
friend Complex operator (const Complex& lsh, const Complex& rhs)
{
return Complex(lsh.m_real rhs.m_real, lsh.m_image rhs.m_image);
}
// Complex double友元版本:允许一个complex对象和另一个double对象相加
// 只能是Complex double,不能是double Complex
friend Complex operator (const Complex& lsh, double rhs)
{
return Complex(lsh.m_real rhs, lsh.m_image);
}
// double Complex友元版本:允许一个double对象和另一个Complex对象相加
//只能是double Complex,不能是Complex double
//和上面的Complex double友元版本相辅相成
friend Complex operator (double lhs, const Complex& rhs)
{
return Complex(lhs rhs.m_real, rhs.m_image);
}
private:
double m_real;
double m_image;
};
void friendFunc()
{
std::cout << "virtualFunc()" << std::endl;
}
void friendFunc(int oneParam)
{
std::cout << "virtualFunc(int oneParam)" << std::endl;
}
运算符重载:运算符成员式重载,运算符友元式重载。
注:见Complex类定义中的运算符重载部分!
在C 中,泛型编程(Generic Programming) 是通关过模板来实现的,然而模板不是与上述两种编程范例有所不同,它必须依附于上述的某种范例,在某范例的基础上来实现,就像面向对象和过程化编程的关系一样。下面就是模板分类:
按泛化对象可分为:
1)类型泛化(Type):
template
class List {
// ...
};
List iList; // iList是能够存储int类型的链表对象
2)数值泛化(Value):
template
class Bit {
// ...
};
Bit<3> bit3; // bit3是长度为3位的位对象
3)数值和类型泛化(Type & Value):
template
class Array {
// ...
};
Array iArray3; // iArray3是能够存储3个int类型的数组对象
按泛化的载体可分为:
函数模板:
template
void functionGeneric()
{
// ...
}
类模板:
template
class classGeneric {
// ...
};