C++ 类 & 对象
C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心特性,通常被称为用户定义的类型。
类用于指定对象的形式,是一种用户自定义的数据类型,它是一种封装了数据和函数的组合。类中的数据称为成员变量,函数称为成员函数。类可以被看作是一种模板,可以用来创建具有相同属性和行为的多个对象。
C++ 类定义
定义一个类需要使用关键字 class,然后指定类的名称,并类的主体是包含在一对花括号中,主体包含类的成员变量和成员函数。
定义一个类,本质上是定义一个数据类型的蓝图,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。
以下实例我们使用关键字 class 定义 Box 数据类型,包含了三个成员变量 length、breadth 和 height:
class Box {public: double length; // 盒子的长度
double breadth; // 盒子的宽度
double height; // 盒子的高度
};
关键字 public 确定了类成员的访问属性。在类对象作用域内,公共成员在类的外部是可访问的。您也可以指定类的成员为 private 或 protected,这个我们稍后会进行讲解。
定义 C++ 对象
类提供了对象的蓝图,所以基本上,对象是根据类来创建的。声明类的对象,就像声明基本类型的变量一样。下面的语句声明了类 Box 的两个对象:
Box Box1; // 声明 Box1,类型为
BoxBox Box2; // 声明 Box2,类型为 Box
对象 Box1 和 Box2 都有它们各自的数据成员。
访问数据成员
类的对象的公共数据成员可以使用直接成员访问运算符 . 来访问。
为了更好地理解这些概念,让我们尝试一下下面的实例:实例
#include <iostream>using namespace std; class Box { public: double length; // 长度
double breadth; // 宽度
double height; // 高度
// 成员函数声明
double get(void); void set( double len, double bre, double hei );};
// 成员函数定义
double Box::get(void) { return length * breadth * height;} void Box::set( double len, double bre, double hei) { length = len; breadth = bre; height = hei;} int **in( ){ Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
Box Box3; // 声明 Box3,类型为 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.height * Box1.length * Box1.breadth; cout << "Box1 的体积:" << volume <<endl; // box 2 的体积 volume = Box2.height * Box2.length * Box2.breadth; cout << "Box2 的体积:" << volume <<endl;
// box 3 详述
Box3.set(16.0, 8.0, 12.0); volume = Box3.get(); cout << "Box3 的体积:" << volume <<endl; return 0;}
当上面的代码被编译和执行时,它会产生下列结果:
Box1的体积:210
Box2的体积:1560
Box3的体积:1536
需要注意的是,私有的成员和受保护的成员不能使用直接成员访问运算符 (.) 来直接访问。我们将在后续的教程中学习如何访问私有成员和受保护的成员。
类 & 对象详解
到目前为止,我们已经对 C++ 的类和对象有了基本的了解。下面的列表中还列出了其他一些 C++ 类和对象相关的概念,可以点击相应的链接进行学习。
概念 | 描述 |
类成员函数 | 类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。 |
类访问修饰符 | 类成员可以被定义为 public、private 或 protected。默认情况下是定义为 private。 |
构造函数 & 析构函数 | 类的构造函数是一种特殊的函数,在创建一个新的对象时调用。类的析构函数也是一种特殊的函数,在删除所创建的对象时调用。 |
C++ 拷贝构造函数 | 拷贝构造函数,是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。 |
C++ 友元函数 | 友元函数可以访问类的 private 和 protected 成员。 |
C++ 内联函数 | 通过内联函数,编译器试图在调用函数的地方扩展函数体中的代码。 |
C++ 中的 this 指针 | 每个对象都有一个特殊的指针 this,它指向对象本身。 |
C++ 中指向类的指针 | 指向类的指针方式如同指向结构的指针。实际上,类可以看成是一个带有函数的结构。 |
C++ 类的静态成员 | 类的数据成员和函数成员都可以被声明为静态的。 |
有public, protected, private三种继承方式,它们相应地改变了基类成员的访问属性。
1.public 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:public, protected, private
2.protected 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:protected, protected, private
3.private 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:private, private, private
但无论哪种继承方式,上面两点都没有改变:
1.private 成员只能被本类成员(类内)和友元访问,不能被派生类访问;
2.protected 成员可以被派生类访问。
C++ 友元函数
类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。
友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。
如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend,如下所示:
class Box{ double width;public: double length; friend void printWidth( Box box ); void setWidth( double wid );};
声明类 ClassTwo 的所有成员函数作为类 ClassOne 的友元,需要在类 ClassOne 的定义中放置如下声明:
friend class ClassTwo;
请看下面的程序:实例
#include <iostream>using namespace std; class Box{ double width; public: friend void printWidth( Box box ); void setWidth( double wid );}; // 成员函数定义void Box::setWidth( double wid ){ width = wid;} // 请注意:printWidth() 不是任何类的成员函数 void printWidth( Box box ){ /* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */ cout << "Width of box : " << box.width <<endl; } // 程序的主函数 int **in( ){ Box box; // 使用成员函数设置宽度 box.setWidth(10.0); // 使用友元函数输出宽度 printWidth( box ); return 0;}
当上面的代码被编译和执行时,它会产生下列结果:
Width of box : 10
对教程中的例子,稍加修改,添加了友元类的使用。
#include <iostream>
using namespace std;
class Box
{
double width;
public:
friend void printWidth(Box box);
friend class BigBox;
void setWidth(double wid);
};
class BigBox
{
public :
void Print(int width, Box &box)
{
// BigBox是Box的友元类,它可以直接访问Box类的任何成员
box.setWidth(width);
cout << "Width of box : " << 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 **in()
{
Box box;
BigBox big;
// 使用成员函数设置宽度
box.setWidth(10.0);
// 使用友元函数输出宽度
printWidth(box);
// 使用友元类中的方法设置宽度
big.Print(20, box);
getchar();
return 0;
}
C++ 内联函数
C++ 内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。
对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编译器需要重新更换一次所有的代码,否则将会继续使用旧的函数。
如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字 inline,在调用函数之前需要对函数进行定义。如果已定义的函数多于一行,编译器会忽略 inline 限定符。
在类定义中的定义的函数都是内联函数,即使没有使用 inline 说明符。
下面是一个实例,使用内联函数来返回两个数中的较大值:
#include <iostream>
using namespace std;
inline int Max(int x, int y)
{
return (x > y)? x : y;
}
// 程序的主函数
int **in( )
{
cout << "Max (20,10): " << Max(20,10) << endl;
cout << "Max (0,200): " << Max(0,200) << endl;
cout << "Max (100,1010): " << Max(100,1010) << endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Max (20,10): 20
Max (0,200): 200
Max (100,1010): 1010
C++ 类的静态成员
我们可以使用 static 关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。
下面的实例有助于更好地理解静态成员数据的概念:实例
#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; }private: double length; // 长度
double breadth; // 宽度
double height; // 高度}; // 初始化类 Box 的静态成员int Box::objectCount = 0; int **in(void){ Box Box1(3.3, 1.2, 1.5); // 声明 box1
Box Box2(8.5, 6.0, 2.0); // 声明 box2
// 输出对象的总数
cout << "Total objects: " << Box::objectCount << endl; return 0;}
当上面的代码被编译和执行时,它会产生下列结果:
Constructor called.
Constructor called.
Total objects: 2
静态成员函数
如果把函数成员声明为静态的,就可以把函数与类的任何特定对象独立开来。静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符 :: 就可以访问。
静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数。
静态成员函数有一个类范围,他们不能访问类的 this 指针。您可以使用静态成员函数来判断类的某些对象是否已被创建。
静态成员函数与普通成员函数的区别:
静态成员函数没有 this 指针,只能访问静态成员(包括静态成员变量和静态成员函数)。
普通成员函数有 this 指针,可以访问类中的任意成员;而静态成员函数没有 this 指针。
下面的实例有助于更好地理解静态成员函数的概念:实例
#include <iostream>usingnamespace 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: doublelength; // 长度
double breadth; // 宽度
double height; // 高度
}; // 初始化类 Box 的静态成员int Box::objectCount = 0;
int **in(void){
// 在创建对象之前输出对象的总数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; return0;}
当上面的代码被编译和执行时,它会产生下列结果:
Inital Stage Count: 0
Constructor called.
Constructor called.
Final Stage Count: 2
1
*声明:内容来源于网络收集和整理,版权归原著所有,如来源信息有误或侵犯权益,请联系站长作修改和删除处理。