C++ 面向对象的一些总结

本文深入探讨C++的高级特性,包括命名空间、内联函数、重载函数、类和对象的概念,构造与析构函数的细节,this指针与静态成员的运用,友元函数的访问控制,类的继承与多态性,以及模板的灵活应用。

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

目录

基本概念

1.命名空间

2.内联函数

3.重载函数

 

类和对象

1.类和对象

2.类的构造函数和析构函数

2.1构造函数和析构函数的简单操作,并且介绍了一些其他函数的初始化方法。

2.2 拷贝构造函数

 3.this 指针和指向类的指针

4.类的静态成员

5. 友元函数

 类的继承

1.基类与派生类

2.访问特征

2.1派生类成员函数对基类成员的访问

2.2派生类对象对基类成员的访问

 多态性

1.多态和虚函数

2.重载运算符

2.1 operator+

2.2 递增运算符( ++ )和递减运算符( -- )

模板

1.函数模板


 


基本概念

1.命名空间

#include <iostream>

using namespace std;   //这也是一个命名空间,通用std  
using std::cout;   //命名空间只限制 通用 std::cout , cin等无影响
class A{
public:
    int fun();  //声明函数而不定义
}
int A::fun(){   //在类的外部使用::来对函数定义
    ....    
}

 适用::来说明使用的是哪里的函数或者变量

::如果前面没有任何说名指变量的时候,指的是全局变量。

2.内联函数

C++ 内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。

    引入内联函数的目的是为了解决程序中函数调用的效率问题,这么说吧,程序在编译器编译的时候,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换,而对于其他的函数,都是在运行时候才被替代。这其实就是个空间代价换时间的i节省。所以内联函数一般都是1-5行的小函数。在使用内联函数时要留神:

1.在内联函数内不允许使用循环语句和开关语句;
2.内联函数的定义必须出现在内联函数第一次调用之前;
3.类结构中所在的类说明内部定义的函数是内联函数。
//内联函数定义    
inline int Max(int x, int y)
{
    return (x > y) ? x : y;
}
int main(void)
{
 //内联函数部分
    cout << "Max (20,10): " << Max(20, 10) << endl;
    cout << "Max (0,200): " << Max(0, 200) << endl;
    cout << "Max (100,1010): " << Max(100, 1010) << endl;
    cout << endl;
}

 运行结果
Max (20,10): 20
Max (0,200): 200
Max (100,1010): 1010

可以明显的看出来,内联函数和其他函数的使用没有太大的区别,

3.重载函数

C++ 允许在同一作用域中的某个函数指定多个定义,称为函数重载。

 

#include <iostream>
using namespace std;

class printData
{
public:
	void print(int i) {
		cout << "整数为: " << i << endl;
	}
	void print(double  f) { //对函数进行重载
		cout << "浮点数为: " << f << endl;
	}
	void print(char c[]) { // 对函数进行重载
		cout << "字符串为: " << c << endl;
	}
};

 下面我们来写程序说明

int main(void)
{
	printData pd;

	// 输出整数
	pd.print(5);
	// 输出浮点数
	pd.print(500.263);
	// 输出字符串
	char c[] = "Hello C++";
	pd.print(c);
}
/*
运行结果
整数为: 5
浮点数为: 500.263
字符串为: Hello C++
*/

类和对象

1.类和对象

首先让我们先定义一个类,如下

#include <iostream>

using namespace std;

class Box         //类的定义,
{
public:     //公有成员   访问修饰符,也可以为private,protected
	double length;   // 长度 类的属性,
	double breadth;  // 宽度 类的属性,
	double height;   // 高度 类的属性,
	double getVolume(void)    //类的成员函数 ,也可以先声明后再外部定义
	{
		return length * breadth * height;
	}
};

对于类的成员函数getVolume(void) 虽然可以在外部定义,但是外部和内部只能存在一个定义,并且只能有一次定义,
在内部定义以后外部就不能定义了,在外部定义的话内部就不能存在定义;(要弄清楚定义和声明的区别)
下面是在外部定义的写法

double Box::getVolume(void)    //在外部定义的时候需要加上作用域符号 :: 作用域符号前需要加类名来表示谁的成员函数   
{
    return length * breadth * height;
}

下面让我们来写主函数来实现这个程序

int main()
{
    Box Box1;        // 声明 Box1,类型为 Box    创建对象
    Box Box2;        // 声明 Box2,类型为 Box    创建对象
    double volume = 0.0;     // 用于存储体积

    // 对 box 1 的成员进行赋值
    Box1.height = 5.0;  
    Box1.length = 6.0;
    Box1.breadth = 7.0;

    // 对 box 2 的成员进行赋值
    Box2.height = 10.0;
    Box2.length = 12.0;
    Box2.breadth = 13.0;

    // box 1 的体积
    volume = Box1.getVolume(); // 调用成员函数
    cout << "Box1 的体积:" << volume << endl;

    // box 2 的体积
    volume = Box2.getVolume(); // 调用成员函数
    cout << "Box2 的体积:" << volume << endl;
    return 0;
}/*

可以看到,我们创建了类Box的两个对象Box1和Box2,并且给予其函数进行了赋值,然后调用了他们的成员函数volume来实现我们需要的操作。运行的结果如下:

 Box1 的体积:210
 Box2 的体积:1560

2.类的构造函数和析构函数

2.1构造函数和析构函数的简单操作,并且介绍了一些其他函数的初始化方法。

注意:即使我们不定义构造和析构函数,系统也会默认自动构造一个构造函数和析构函数

和类名相同的函数就是构造函数,每次创建类的对象时,都会执行一次构造函数 构造函数也可以没有参数

在构造函数的前面加上~就是析构函数,它不会返回任何值,也不能带任何参数,析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。

#include <iostream>
using namespace std;

class Line{
	public:
		void setLength(double len); //成员函数
		double getLength(void);
		Line(double len);  // 这是构造函数 每次创建类的对象时,都会执行一次构造函数 构造函数也可以没有参数
		~Line(); //析构函数,在构造函数的前面加上~,它不会返回任何值,也不能带任何参数,析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
	private:
		double length;
};

// 成员函数定义,包括构造函数   
Line::Line(double len){
	cout << "Object is being created" << endl; //每次创建类的对象将会触发该语句
	length = len;      // 初始化 length
}

// 析构函数 
Line::~Line(void) {
    cout<<"Object is being deleted" << endl;  //将会在程序结束后执行,
}

// 成员函数
void Line::setLength(double len)
{
    length = len;
}
double Line::getLength(void)
{
    return length;
}

可以看到,构造函数也可以在类外进行定义,下面我们介绍一些其他的初始化方法效果和上面的一样

Line::Line(double len) : length(len) {   //初始化列表的方式来初始化字段 效果同上  多个参数时,用逗号隔开 如下
    cout << "Object is being created" << endl;    
} 

假设有一个类 C,具有多个字段 X、Y、Z 等需要进行初始化,同理地,你也可以使用上面的语法,只需要在不同的字段使用逗号进行分隔,

C::C(double a,double b ,double c):X(a),Y(b),Z(c){
    ....
}

 注意:C++ 初始化类成员时,是按照声明的顺序初始化的而不是按照出现在初始化列表的顺序初始化的!
           最好按照声明的顺序来写,初始化列表的顺序。

最后我们创建程序的主函数来实现这个程序,
值得注意的是,当构造函数有参数的时候,创建对象需要初始化参数,具体如下

int main()
{
    Line line(10.0); //当构造函数有参数时,创建对象需要初始化参数

    // 获取默认设置的长度
    cout << "Length of line : " << line.getLength() << endl;
    // 再次设置长度
    line.setLength(6.0); // 调用成员函数来修改类的成员的值
    cout << "Length of line : " << line.getLength() << endl;

    return 0;
}

值得注意的是,私有的成员的值只能通过该类的成员函数来修改,这一点在后面的部分会详细的介绍。

运行结果
Object is being created
Length of line : 10
Length of line : 6
Object is being deleted

2.2 拷贝构造函数

拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:

 通过使用另一个同类型的对象来初始化新创建的对象。
复制对象把它作为参数传递给函数。

复制对象,并从函数返回这个对象。

如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数

下面我们来简单介绍拷贝构造函数的操作

/*拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:
	通过使用另一个同类型的对象来初始化新创建的对象。
	复制对象把它作为参数传递给函数。
	复制对象,并从函数返回这个对象。
	如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数
*/
#include <iostream>

using namespace std;

class Line
{
public:
	int getLength(void);
	Line(int len);             // 简单的构造函数
	Line(const Line &obj);      // 拷贝构造函数
	~Line();                     // 析构函数

private:
	int *ptr;  //声明一个整型指针变量 ptr
};

// 成员函数定义,包括构造函数
Line::Line(int len)   //构造函数
{ 
	cout << "调用构造函数" << endl;
	// 为指针分配内存
	ptr = new int;    //申请动态分配一个 int 型存储区,并将首地址赋给 ptr
	*ptr = len;
}

Line::Line(const Line &obj) //拷贝构造函数
{
	cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
	//为指针分配内存, 下面为不同点
	ptr = new int;
	*ptr = *obj.ptr; // 拷贝值    将obj的值传给ptr
}

Line::~Line(void)
{
	cout << "释放内存" << endl;
	delete ptr;
}
int Line::getLength(void)
{
	return *ptr;
}

void display(Line obj)  //注意这个不是类的成员函数,需要调用形参
{
	cout << "line 大小 : " << obj.getLength() << endl;
}

// 程序的主函数
int main()
{
	Line line1(10); 
	cout << "       " << endl;
	Line line2 = line1; // 这里也调用了拷贝构造函数
	//此处隔开看的比较明白, 
	cout << "       " << endl;
	display(line1);    // 复制对象把它作为参数传递给函数,使用结束后释放内存 
	//此处隔开看的比较明白,
	cout << "        " << endl;
	display(line2);
	//此处隔开看的比较明白,
	cout << "        " << endl;
	return 0;
}

/*
运行结果
调用构造函数

调用拷贝构造函数并为指针 ptr 分配内存

调用拷贝构造函数并为指针 ptr 分配内存
line 大小 : 10
释放内存

调用拷贝构造函数并为指针 ptr 分配内存
line 大小 : 10
释放内存

释放内存
释放内存
请按任意键继续. . .

*/

可以看出来我把输出结果分成了五段,

第一段创建对象Line1,系统自动调用构造函数,

第二段创建对象Line2并将Line1 赋值给他,系统自动调用第一个对象的拷贝构造函数,并将第一个对象的成员值赋值给第二个对象的成员值。

第三段调用非成员函数,以形参的形式,系统自动调用对象的拷贝构造函数,并给形参赋值,使用结束后,调用对应形参的析构函数释放掉内存。

第四段和第三段雷同,区别在于对应的对象不同;

第五段是程序执行结束后,释放掉我们在第一段和第二段创建的ptr申请的空间

 3.this 指针和指向类的指针

在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。友元函数没有 this 指针,因为友元不是类的成员。只有成员函数才有 this 指针

  一个指向 C++ 类的指针与指向结构的指针类似,访问指向类的指针的成员,需要使用成员访问运算符 ->,就像访问指向结构的指针一样。与所有的指针一样,您必须在使用指针之前,对指针进行初始化

#include <iostream>

using namespace std;

class Box
{
public:
	// 构造函数定义
	Box(double l = 2.0, double b = 2.0, double h = 2.0)
	{
		cout << "Constructor called." << endl;
		length = l;
		breadth = b;
		height = h;
	}
	double Volume()
	{
		return length * breadth * height;
	}
	int compare(Box box)
	{
		return this->Volume() > box.Volume();  //this->fun()等价于,调用这个函数的对象->fun()
	}
private:
	double length;     // Length of a box
	double breadth;    // Breadth of a box
	double height;     // Height of a box
};

this->fun()等价于,调用这个函数的对象->fun(),下面举例说明

int main(void)
{
    Box Box1(3.3, 1.2, 1.5);    // Declare box1
    Box Box2(8.5, 6.0, 2.0);    // Declare box2
    Box *ptrBox;

    if (Box1.compare(Box2))   //此处比较的是Box1和Box2的大小
    {
        cout << "Box2 is smaller than Box1" << endl;
    }
    else
    {
        cout << "Box2 is equal to or larger than Box1" << endl;
    }
    // 保存第一个对象的地址 指向第一个对象的地址
    ptrBox = &Box1;

    // 现在尝试使用成员访问运算符来访问成员
    cout << "Volume of Box1: " << ptrBox->Volume() << endl;

    // 保存第二个对象的地址
    ptrBox = &Box2;

    // 现在尝试使用成员访问运算符来访问成员
    cout << "Volume of Box2: " << ptrBox->Volume() << endl;

    return 0;
}

运行结果
Constructor called.
Constructor called.
Box2 is equal to or larger than Box1
Volume of Box1: 5.94
Volume of Box2: 102

4.类的静态成员

我们可以使用 static 关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。

静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零。

我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化,

如果把函数成员声明为静态的,就可以把函数与类的任何特定对象独立开来。静态成员函数即使在类对象不存在的情况下也能被调用,

静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数。
静态成员函数有一个类范围,他们不能访问类的 this 指针。您可以使用静态成员函数来判断类的某些对象是否已被创建。静态函数只要使用类名加范围解析运算符 :: 就可以访问。

静态成员函数与普通成员函数的区别:

   静态成员函数没有 this 指针,只能访问静态成员(包括静态成员变量和静态成员函数)。
普通成员函数有 this 指针,可以访问类中的任意成员;而静态成员函数没有 this 指针。

 

#include <iostream>

using namespace std;

class Box
{
public:
	static int objectCount; //静态的成员 该类的所有对象共用此成员
	// 构造函数定义
	Box(double l = 2.0, double b = 2.0, double h = 2.0) //构造函数
	{
		cout << "Constructor called." << endl;
		length = l;
		breadth = b;
		height = h;
		// 每次创建对象时增加 1
		objectCount++;
	}
	double Volume()
	{
		return length * breadth * height;
	}
	static int getCount() {
		return objectCount;
	}
private:
	double length;     // 长度
	double breadth;    // 宽度
	double height;     // 高度
};

// 初始化类 Box 的静态成员   静态成员的初始化只能放在类的外面
int Box::objectCount = 0;

此处要特别注意,静态成员的初始化只能在类的外面使用::作用域符号来进行初始化,该类的每个对象都有修改静态成员的权利

int main(){
    //静态成员部分
    // 在创建对象之前输出对象的总数
    cout << "Inital Stage Count: " << Box::getCount() << endl;
    Box Box1(3.3, 1.2, 1.5);    // 声明 box1
    Box Box2(8.5, 6.0, 2.0);    // 声明 box2


    // 在创建对象之后输出对象的总数
    cout << "Final Stage Count: " << Box::getCount() << endl; //使用静态成员函数
    cout << "Total objects: " << Box::objectCount << endl; //使用静态成员

    return 0;
}

运行结果
Inital Stage Count: 0
Constructor called.
Constructor called.
Final Stage Count: 2
Total objects: 2

5. 友元函数

类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。
尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。

    要访问非static成员时,需要对象做参数;
    要访问static成员或全局变量时,则不需要对象做参数;
    如果做参数的对象是全局对象,则不需要对象做参数.可以直接调用友元函数,不需要通过对象或指针

#include <iostream>

using namespace std;   //这也是一个命名空间,通用std  

class Box
{
	double width;
public:
	friend void printWidth(Box box); //友元函数
	void setWidth(double wid);
	friend class Bigbox; //声明类Bigbox的所有成员作为类Box的友元
};
class BigBox
{
public:
	void Print(int width, Box &box)
	{
		// BigBox是Box的友元类,它可以直接访问Box类的任何成员
		box.setWidth(width);
		cout << "Width of box : " << width << endl;
	}
};

// 成员函数定义
void Box::setWidth(double wid)
{
	width = wid;
}

// 请注意:printWidth() 不是任何类的成员函数
void printWidth(Box box)
{
	/* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */
	cout << "Width of box : " << box.width << endl;
}

// 程序的主函数
int main()
{
	Box box;
	BigBox big;

	// 使用成员函数设置宽度
	box.setWidth(10.0);

	// 使用友元函数输出宽度
	printWidth(box);

	// 使用友元类中的方法设置宽度
	big.Print(20, box);

	return 0;
}
 /*
 运行结果
 Width of box : 10
 Width of box : 20
 */

 类的继承

1.基类与派生类

派生类可以访问基类中所有的非私有成员。因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。 我们可以根据访问权限总结出不同的访问类型,如下所示

访问该类publicprotectedprivate
同一个类访问yesyesyes
派生类访问基类yesyesno
外部的类访问yesnono

一个派生类继承了所有的基类方法,但下列情况除外:
    基类的构造函数、析构函数和拷贝构造函数。
    基类的重载运算符。
    基类的友元函数。 

 下面我们先定义两个基类

#include <iostream>

using namespace std;

// 基类 Shape
class Shape
{
public:  //公有成员在程序中类的外部是可访问的。您可以不使用任何成员函数来设置和获取公有变量的值 类名.变量即可
	void setWidth(int w)
	{
		width = w;
	}
	void setHeight(int h)
	{
		height = h;
	}
protected:  //保护成员变量或函数与私有成员十分相似,但有一点不同,保护成员在派生类(即子类)中是可访问的。
	int width;  //可以被派生类进行访问
	int height;
private:  //私有成员变量或函数在类的外部是不可访问的,甚至是不可查看的。只有类和友元函数可以访问私有成员。
	double length; // 可以使用类的成员函数来对私有成员进行访问和修改
};
// 基类 PaintCost
class PaintCost
{
public:
	int getCost(int area)
	{
		return area * 70;
	}
};

  Rectanle公共 继承了Shape和PaintCost两个类 ,也可以是private或protected继承区别在于成员的不同

此处表现得是多继承

class Rectangle : public Shape, public PaintCost  //Rectanle继承了Shape和PaintCost两个类
{
public:
    int getArea()
    {
        return (width * height);
    }
};

 下面我们来实现这个程序

int main(void)
{
    //继承部分
    Rectangle Rect;
    int area;

    Rect.setWidth(5);
    Rect.setHeight(7);
    area = Rect.getArea();
    // 输出对象的面积
    cout << "Total area: " << Rect.getArea() << endl;
    // 输出总花费
    cout << "Total paint cost: $" << Rect.getCost(area) << endl;
}
/*
运行结果
Total area: 35
Total paint cost: $2450
*/

2.访问特征

2.1派生类成员函数对基类成员的访问

 公有继承(public):
当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,
基类的保护成员也是派生类的保护成员,
基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。

保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。

私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。

下面我们再举例说明:三种不同的继承

class A {
public:
    int a;
    A() { //构造函数
        a1 = 1;
        a2 = 2;
        a3 = 3;
        a = 4;
    }
    void fun() {
        cout << a << endl;    //正确
        cout << a1 << endl;   //正确
        cout << a2 << endl;   //正确
        cout << a3 << endl;   //正确
    }
public:
    int a1;
protected:
    int a2;
private:
    int a3;
};
//公共继承 
class B : public A {
public:
    int a;
    B(int i) { //构造函数
        A();
        a = i;
    }
    void fun() {
        cout << a << endl;       //正确,public成员
        cout << a1 << endl;       //正确,基类的public成员,在派生类中仍是public成员。
        cout << a2 << endl;       //正确,基类的protected成员,在派生类中仍是protected可以被派生类访问。
        cout << a3 << endl;       //错误,基类的private成员不能被派生类访问。
    }
};
//保护继承
class B : protected A {
public:
    int a;
    B(int i) {
        A();
        a = i;
    }
    void fun() {
        cout << a << endl;       //正确,public成员。
        cout << a1 << endl;       //正确,基类的public成员,在派生类中变成了protected,可以被派生类访问。
        cout << a2 << endl;       //正确,基类的protected成员,在派生类中还是protected,可以被派生类访问。
        cout << a3 << endl;       //错误,基类的private成员不能被派生类访问。
    }
};
//私有继承
class B : private A {
public:
    int a;
    B(int i) {
        A();
        a = i;
    }
    void fun() {
        cout << a << endl;       //正确,public成员。
        cout << a1 << endl;       //正确,基类public成员,在派生类中变成了private,可以被派生类访问。
        cout << a2 << endl;       //正确,基类的protected成员,在派生类中变成了private,可以被派生类访问。
        cout << a3 << endl;       //错误,基类的private成员不能被派生类访问。
    }
};

值得注意的是无论那种继承 基类的私有成员都是不能被派生类进行访问的。

2.2派生类对象对基类成员的访问

int main(void)
{
    //公共继承
    B b(10);
    cout << b.a << endl;
    cout << b.a1 << endl;   //正确
    cout << b.a2 << endl;   //错误,类外不能访问protected成员
    cout << b.a3 << endl;   //错误,类外不能访问private成员
    //保护继承
    B b(10);
    cout << b.a << endl;       //正确。public成员
    cout << b.a1 << endl;      //错误,protected成员不能在类外访问。  此处发生了改变
    cout << b.a2 << endl;      //错误,protected成员不能在类外访问。
    cout << b.a3 << endl;      //错误,private成员不能在类外访问
    //私有继承
    B b(10);
    cout << b.a << endl;       //正确。public成员
    cout << b.a1 << endl;      //错误,private成员不能在类外访问。
    cout << b.a2 << endl;      //错误, private成员不能在类外访问。   
    cout << b.a3 << endl;      //错误,private成员不能在类外访问。
    return 0;
}

保护继承的时候B的对象b不能访问基类的a1因为此时a1对于b来说已经是protected的成员了.

 多态性

1.多态和虚函数

C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。

#include <iostream> 
using namespace std;

class Shape {
protected:
	int width, height;
public:
	Shape(int a = 0, int b = 0)
	{
		width = a;
		height = b;
	}
	void setWidth(int w)
	{
		width = w;
	}
	void setHeight(int h)
	{
		height = h;
	}

    虚函数 是在基类中使用关键字 virtual 声明的函数。
    在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
    我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,
    这种操作被称为动态链接,或后期绑定。

 virtual int area() //虚函数     //如果不加virtual 为静态链接 - 函数调用在程序执行前就准备好了。有时候这也被称为早绑定,
    {
        cout << "Parent class area :" << endl;
        return 0;
    }
    virtual int getArea() = 0;  //纯虚函数,没有主体;
};

 没有主体的虚函数称为纯虚函数,

class Rectangle : public Shape {
public:
    Rectangle(int a = 0, int b = 0) :Shape(a, b) { }
    int area()
    {
        cout << "Rectangle class area :" << endl;
        return (width * height);
    }
    int getArea()
    {
        return (width * height);
    }
};
class Triangle : public Shape {
public:
    Triangle(int a = 0, int b = 0) :Shape(a, b) { }
    int area()
    {
        cout << "Triangle class area :" << endl;
        return (width * height / 2);
    }
    int getArea()
    {
        return (width * height) / 2;
    }
};

下面我们来实现这个程序

// 程序的主函数
int main()
{
    Shape *shape; //指向类的指针
    Rectangle rec(10, 7);
    Triangle  tri(10, 5);
    // 存储矩形的地址
    shape = &rec;
    // 调用矩形的求面积函数 area
    shape->area();
    // 存储三角形的地址
    shape = &tri;
    // 调用三角形的求面积函数 area
    shape->area();

    Rectangle Rect;
    Triangle  Tri;

    Rect.setWidth(5);
    Rect.setHeight(7);
    // 输出对象的面积
    cout << "Total Rectangle area: " << Rect.getArea() << endl;

    Tri.setWidth(5);
    Tri.setHeight(7);
    // 输出对象的面积
    cout << "Total Triangle area: " << Tri.getArea() << endl;

    return 0;
}
/*
运行结果
Rectangle class area :
Triangle class area :
Total Rectangle area: 35
Total Triangle area: 17
*/

2.重载运算符

2.1 operator+

C++ 允许在同一作用域中的运算符指定多个定义,称为运算符重载。

#include <iostream>
using namespace std;

class Box{
public:

	double getVolume(void){
		return length * breadth * height;
	}
	void setLength(double len){
		length = len;
	}
	void setBreadth(double bre){
		breadth = bre;
	}
	void setHeight(double hei){
		height = hei;
	}
	// 重载 + 运算符,用于把两个 Box 对象相加
	Box operator+(const Box& b)   //返回对象 + 关键字 operator+ 
	{
		Box box; 
		box.length = this->length + b.length;
		box.breadth = this->breadth + b.breadth;
		box.height = this->height + b.height;
		return box;
	}
private:
	double length;      // 长度
	double breadth;     // 宽度
	double height;      // 高度
};

int main(void)
{
	Box Box1;                // 声明 Box1,类型为 Box
	Box Box2;                // 声明 Box2,类型为 Box
	Box Box3;                // 声明 Box3,类型为 Box
	double volume = 0.0;     // 把体积存储在该变量中
	// Box1 详述
	Box1.setLength(6.0);
	Box1.setBreadth(7.0);
	Box1.setHeight(5.0);
	// Box2 详述
	Box2.setLength(12.0);
	Box2.setBreadth(13.0);
	Box2.setHeight(10.0);

	// Box1 的体积
	volume = Box1.getVolume();
	cout << "Volume of Box1 : " << volume << endl;
	// Box2 的体积
	volume = Box2.getVolume();
	cout << "Volume of Box2 : " << volume << endl;

	// 把两个对象相加,得到 Box3
	Box3 = Box1 + Box2;

	// Box3 的体积
	volume = Box3.getVolume();
	cout << "Volume of Box3 : " << volume << endl;
	return 0;
}

/*
运行结果
Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400
*/

2.2 递增运算符( ++ )和递减运算符( -- )

递增运算符( ++ )和递减运算符( -- )是 C++ 语言中两个重要的一元运算符。

#include <iostream>
using namespace std;

class Time
{
private:
	int hours;             // 0 到 23
	int minutes;           // 0 到 59
public:
	// 所需的构造函数
	Time() {
		hours = 0;
		minutes = 0;
	}
	Time(int h, int m) {
		hours = h;
		minutes = m;
	}
	// 显示时间的方法
	void displayTime()
	{
		cout << "H: " << hours << " M:" << minutes << endl;
	}
	// 重载前缀递增运算符( ++i )
	Time operator++ ()
	{
		++minutes;          // 对象加 1
		if (minutes >= 60)
		{
			++hours;
			minutes -= 60;
		}
		return Time(hours, minutes);
	}
	// 重载后缀递增运算符( i++ )
	Time operator++(int)
	{
		// 保存原始值
		Time T(hours, minutes);
		// 对象加 1
		++minutes;
		if (minutes >= 60)
		{
			++hours;
			minutes -= 60;
		}
		// 返回旧的原始值
		return T;
	}
};
int main()
{
	Time T1(11, 59), T2(10, 40);

	++T1;                    // T1 加 1
	T1.displayTime();        // 显示 T1
	++T1;                    // T1 再加 1
	T1.displayTime();        // 显示 T1

	T2++;                    // T2 加 1
	T2.displayTime();        // 显示 T2
	T2++;                    // T2 再加 1
	T2.displayTime();        // 显示 T2
	return 0;
}
/*
运行结果
H: 12 M:0
H: 12 M:1
H: 10 M:41
H: 10 M:42
*/

模板

1.函数模板

#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>

using namespace std;

template <typename T1> //函数模板
inline T1 const& Max(T1 const& a, T1 const& b)
{
	return a < b ? b : a;
}

int main()
{
	//函数模板
	int i = 39;
	int j = 20;
	cout << "Max(i, j): " << Max(i, j) << endl;
	double f1 = 13.5;
	double f2 = 20.7;
	cout << "Max(f1, f2): " << Max(f1, f2) << endl;
	string s1 = "Hello";
	string s2 = "World";
	cout << "Max(s1, s2): " << Max(s1, s2) << endl;
}
/*
运行结果
Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值