700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 12.c++面向对象——类与对象 成员函数 继承 构造析构 友元函数 this指针 类的静态成员

12.c++面向对象——类与对象 成员函数 继承 构造析构 友元函数 this指针 类的静态成员

时间:2021-11-02 05:20:01

相关推荐

12.c++面向对象——类与对象 成员函数 继承 构造析构 友元函数 this指针 类的静态成员

一.C++类的定义

定义一个类,本质上是定义一个数据类型的蓝图。

类定义是以关键字class开头,后跟类的名称。类的主体是包含在一对花括号中。类定义后必须跟着一个分号或一个声明列表。例如,我们使用关键字 class 定义 Box 数据类型,如下所示:

class Box{public:double length; // 盒子的长度double breadth; // 盒子的宽度double height; // 盒子的高度};

关键字 public 确定了类成员的访问属性。在类对象作用域内,公共成员在类的外部是可访问的。您也可以指定类的成员为 private 或 protected。

二. C++对象

类提供了对象的蓝图,所以基本上,对象是根据类来创建的。声明类的对象,就像声明基本类型的变量一样。下面的语句声明了类 Box 的两个对象:

Box Box1;// 声明 Box1,类型为 BoxBox Box2;// 声明 Box2,类型为 Box

访问数据成员

用点.即可,需要注意的是,私有的成员和受保护的成员不能使用直接成员访问运算符 (.) 来直接访问。我们将在后续的教程中学习如何访问私有成员和受保护的成员。

class Box{public:double length; // 长度double breadth; // 宽度double height; // 高度};int main( ){Box Box1; // 声明 Box1,类型为 BoxBox Box2; // 声明 Box2,类型为 Boxdouble volume = 0.0;// 用于存储体积// box 1 详述Box1.height = 5.0;Box1.length = 6.0;Box1.breadth = 7.0;return 0;}

三.类的成员函数

类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。类成员函数是类的一个成员,它可以操作类的任意对象,可以访问对象中的所有成员。

让我们看看之前定义的类 Box,现在我们要使用成员函数来访问类的成员,而不是直接访问这些类的成员:

class Box{public:double length; // 长度double breadth; // 宽度double height; // 高度double getVolume(void);// 返回体积};

内联函数

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

内联的主要不同是:它会复制源函数代码到调用的位置,而不像普通函数一样进行现场保护、跳转执行然后恢复现场等操作,可以使程序效率提高

成员函数可以定义在类定义内部,在类定义中定义的成员函数把函数声明为内联的,即便没有使用 inline 标识符。所以您可以按照如下方式定义 Volume() 函数:

class Box{public:double length;// 长度double breadth;// 宽度double height;// 高度double getVolume(void){return length * breadth * height;}};

也可以在类的外部使用范围解析运算符 ::定义该函数,在这里,需要强调一点,在 :: 运算符之前必须使用类名。如下所示:

double Box::getVolume(void){return length * breadth * height;}

调用成员函数是在对象上使用点运算符(.),这样它就能操作与该对象相关的数据,如下所示:

Box myBox;// 创建一个对象myBox.getVolume(); // 调用该对象的成员函数

3.1C++ 类访问修饰符

数据封装是面向对象编程的一个重要特点,它防止函数直接访问类类型的内部成员。类成员的访问限制是通过在类主体内部对各个区域标记 public、private、protected 来指定的。关键字 public、private、protected 称为访问修饰符

一个类可以有多个 public、protected 或 private 标记区域。每个标记区域在下一个标记区域开始之前或者在遇到类主体结束右括号之前都是有效的。成员和类的默认访问修饰符是 private

class Base {public:// 公有成员protected:// 受保护成员private:// 私有成员};

3.2私有成员:

私有成员变量或函数在类的外部是不可访问的,甚至是不可查看的。只有类和友元函数可以访问私有成员

举例:

默认情况下,类的所有成员都是私有的。例如在下面的类中,width 是一个私有成员,这意味着,如果您没有使用任何访问修饰符,类的成员将被假定为私有成员:

class Box{double width;public:double length;void setWidth( double wid );double getWidth( void );};

实际操作中,我们一般会在私有区域定义数据,在公有区域定义相关的函数,以便在类的外部也可以调用这些函数,如下所示:

width是一个private变量,我们不可以再main函数中box.width直接访问它,但是我们可以定义一个Public函数 setwidth,用这个共有的函数来访问私有的变量。

void Box::setWidth( double wid ){width = wid;}

即:

#include <iostream>using namespace std;class Box{public:double length;void setWidth( double wid );double getWidth( void );private:double width;};// 成员函数定义double Box::getWidth(void){return width ;}void Box::setWidth( double wid ){width = wid;}// 程序的主函数int main( ){Box box;// 不使用成员函数设置长度box.length = 10.0; // OK: 因为 length 是公有的cout << "Length of box : " << box.length <<endl;// 不使用成员函数设置宽度// box.width = 10.0; // Error: 因为 width 是私有的box.setWidth(10.0); // 使用成员函数设置宽度cout << "Width of box : " << box.getWidth() <<endl;return 0;}

3.3保护成员:

1.private 成员只能被本类成员(类内)和友元访问,不能被派生类访问;

2.protected 成员可以被派生类访问。

保护(protected)成员变量或函数与私有成员十分相似(即也不可以在类外访问protected变量),但有一点不同,保护成员在派生类(即子类)中是可访问的

现在您可以看到下面的实例中,我们从父类 Box 派生了一个子类 smallBox

下面的实例与前面的实例类似,在这里width 成员可被派生类 smallBox 的任何成员函数访问

#include <iostream>using namespace std;class Box{protected:double width;};class SmallBox:Box // SmallBox 是派生类{public:void setSmallWidth( double wid );double getSmallWidth( void );};// 子类的成员函数double SmallBox::getSmallWidth(void){return width ;}void SmallBox::setSmallWidth( double wid ){width = wid;}// 程序的主函数int main( ){SmallBox box;// 使用成员函数设置宽度box.setSmallWidth(5.0);cout << "Width of box : "<< box.getSmallWidth() << endl;return 0;}

四.继承

有public, protected, private三种继承方式,它们相应地改变了基类成员的访问属性。

public 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:public, protected, private(即没变化protected 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:protected, protected, private(除了private其他全被protect,意味着不能类外访问)private 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:private, private, private(全被private)

但无论哪种继承方式,下面两点都没有改变:

private 成员只能被本类成员(类内)和友元访问,不能被派生类访问protected 成员可以被派生类访问

下面举三种继承的例子:

4.1public继承

注意:基类的private成员不能被派生类访问(a3)

#include<iostream>#include<assert.h>using namespace std;//定义A类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; //注意private成员不能被派生的子类访问};//end A//class B public继承A ,中间打冒号即可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成员不能被派生类访问。}};int main(){B b(10);cout << b.a << endl;cout << b.a1 << endl; //正确cout << b.a2 << endl; //错误,类外不能访问protected成员cout << b.a3 << endl; //错误,类外不能访问private成员system("pause");return 0;}

4.2protected继承

#include<iostream>#include<assert.h>using namespace std;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;};//b类 protected继承A 类,中间加冒号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成员不能被派生类访问。}};int main(){B b(10);cout << b.a << endl; //正确。public成员cout << b.a1 << endl;//错误,protected成员不能在类外访问。cout << b.a2 << endl;//错误,protected成员不能在类外访问。cout << b.a3 << endl;//错误,private成员不能在类外访问。system("pause");return 0;}

4.3private 继承

#include<iostream>#include<assert.h>using namespace std;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 : 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成员不能被派生类访问。}};int main(){B b(10);cout << b.a << endl; //正确。public成员cout << b.a1 << endl;//错误,private成员不能在类外访问。cout << b.a2 << endl;//错误, private成员不能在类外访问。cout << b.a3 << endl;//错误,private成员不能在类外访问。system("pause");return 0;}

总结,再看一遍这个表:

4.4继承总结

即:

1.不管怎么继承,派生类都只能访问基类的public和protected变量,无法访问基类的private变量。所以我们一般把数据变量放在private里,避免被派生类的成员函数访问

2.而至于类外访问,只有派生过后仍然是Public的才可以访问。

3.派生类以下内容无法继承:基类的(拷贝)构造,析构函数。基类的重载运算符。基类的友元函数

4.5多继承

一个子类也可以同时继承多个父类。比如你是你爸妈生的,你同时继承爸妈两个基类的特性。

class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…{<派生类类体>};如下例Rectangle同时继承Shape和PaintCost:class Rectangle: public Shape, public PaintCost{public:int getArea(){return (width * height);}};

即在第一个继承之后打逗号接着继承即可。

五.类的构造函数&析构函数

如果程序里没有构造函数和析构函数,编译器在编译的时候会自动生成构造函数和析构函数,只是函数内没有任何操作

5.1构造函数

类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。

构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。

下面的实例有助于更好地理解构造函数的概念:

#include <iostream>using namespace std;class Line{public:void setLength( double len );double getLength( void );Line(); // 这是构造函数private:double length;};// 成员函数定义,包括构造函数Line::Line(void)// 这是构造函数的定义{cout << "Object is being created" << endl;}void Line::setLength( double len ){length = len;}double Line::getLength( void ){return length;}// 程序的主函数int main( ){Line line;// 设置长度line.setLength(6.0); cout << "Length of line : " << line.getLength() <<endl;return 0;}

当上面的代码被编译和执行时,它会产生下列结果:

Object is being createdLength of line : 6

默认的构造函数没有任何参数,但如果需要,构造函数也可以带有参数。这样在创建对象时就会给对象赋初始值,如下面的例子所示:

#include <iostream>using namespace std;class Line{public:void setLength( double len );double getLength( void );Line(double len); // 这是构造函数private:double length;};// 成员函数定义,包括构造函数Line::Line( double len){cout << "Object is being created, length = " << len << endl;length = len;}void Line::setLength( double len ){length = len;}double Line::getLength( void ){return length;}// 程序的主函数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 = 10Length of line : 10Length of line : 6

5.1.1使用初始化列表来初始化字段:(常用)

使用初始化列表来初始化字段:

Line::Line( double len): length(len){cout << "Object is being created, length = " << len << endl;}

上面的语法等同于如下语法:

Line::Line( double len){length = len;cout << "Object is being created, length = " << len << endl;}

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

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

5.1.2拷贝构造函数

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

拷贝构造函数通常用于:

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

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

classname (const classname &obj) {// 构造函数的主体}

在这里,obj 是一个对象引用,该对象是用于初始化另一个对象的。

下面一个具体例子:

使用line作为参数传入display函数中,首先会调用拷贝构造函数对line进行复制使用该副本在函数中进行操作;函数结束后该副本作为局部变量被回收,因此打印释放内存;

#include <iostream>using namespace std;class Line{public:int getLength( void );Line( int len ); // 简单的构造函数Line( const Line &obj);// 拷贝构造函数~Line(); // 析构函数private:int *ptr;};// 成员函数定义,包括构造函数Line::Line(int len){cout << "调用构造函数" << endl;// 为指针分配内存ptr = new int;*ptr = len;}Line::Line(const Line &obj){cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;ptr = new int;*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 line(10);display(line);return 0;}

当上面的代码被编译和执行时,它会产生下列结果:

调用构造函数//Line line(10);调用拷贝构造函数并为指针 ptr 分配内存//因为line要作参数传给display函数line 大小 : 10释放内存//局部变量:被拷贝的line被释放释放内存//主Line被释放

下面的实例对上面的实例稍作修改,通过使用已有的同类型的对象来初始化新创建的对象

display函数过程同上第一段代码,此外,在使用line1实例来初始化对象line2的过程中,同样调用拷贝构造函数,复制得到line2示例;紧接着作为参数又要拷贝构造,完了之后释放,重复两次,因此,第一个释放内存:释放第一个display复制的形参实例;第二个:释放第二个display复制的形参实例;第三四个:return 释放line1和line2;

#include <iostream>using namespace std;class Line{public:int getLength( void );Line( int len ); // 简单的构造函数Line( const Line &obj);// 拷贝构造函数~Line(); // 析构函数private:int *ptr;};// 成员函数定义,包括构造函数Line::Line(int len){cout << "调用构造函数" << endl;// 为指针分配内存ptr = new int;*ptr = len;}Line::Line(const Line &obj){cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;ptr = new int;*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);Line line2 = line1; // 这里也调用了拷贝构造函数display(line1);display(line2);return 0;}

当上面的代码被编译和执行时,它会产生下列结果:

调用构造函数//Line line1(10);调用拷贝构造函数并为指针 ptr 分配内存//Line line2 = line1;调用拷贝构造函数并为指针 ptr 分配内存//display(line1);line 大小 : 10释放内存//delete了参数line1调用拷贝构造函数并为指针 ptr 分配内存//display(line2);line 大小 : 10释放内存//delete了参数line2释放内存//后面两个是主函数return的释放内存

5.2析构函数

类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。

析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。

下面的实例有助于更好地理解析构函数的概念:

#include <iostream>using namespace std;class Line{public:void setLength( double len );double getLength( void );Line(); // 这是构造函数声明~Line(); // 这是析构函数声明private:double length;};// 成员函数定义,包括构造函数Line::Line(void){cout << "Object is being created" << endl;}Line::~Line(void){cout << "Object is being deleted" << endl;}void Line::setLength( double len ){length = len;}double Line::getLength( void ){return length;}// 程序的主函数int main( ){Line line;// 设置长度line.setLength(6.0); cout << "Length of line : " << line.getLength() <<endl;return 0;}

当上面的代码被编译和执行时,它会产生下列结果:

Object is being createdLength of line : 6Object is being deleted

5.3类的构造与析构顺序

构造顺序

先构造父类(如果有的话)按声明顺序创建类的成员类最后执行该类的构造函数

析构顺序

最先执行该类自己的析构函数然后按声明顺序反方向销毁成员类析构父类

示例:

构造示例1:构造一个a类的A,a 需要继承b,所以先构造b;b又有一个成员类c,所以最先构造c。然后构造b。最后构造a。

c b a

class c{public:c(){printf("c\n"); }protected:private:};class b {public:b(){printf("b\n");}protected:c C;private:};class a : public b{public:a(){printf("a\n"); }protected:private:};int main(){a A;getchar();}

构造示例2;

构造一个a类型的A,a需要继承b,所以最先构造b。然后a有成员类c,所以再构造c,最后构造a。

b c a

class c{public:c(){printf("c\n"); }protected:private:};class b {public:b(){printf("b\n");}protected:private:};class a : public b{public:a(){printf("a\n"); }protected:c C;private:};int main(){a A;getchar();}

析构示例

最先析构自己a,然后析构成员类c,最后析构父类b

a c b

class c{public:c(){}~c(){printf("c\n"); }protected:private:};class b {public:b(){}~b(){printf("b\n");}protected:private:};class a : public b{public:a(){}~a(){printf("a\n"); }protected:c C;private:};int main(){a A;return 0;}

六.友元函数

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

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。

友元函声明:

class Box{double width;public:double length;friend void printWidth( Box box );void setWidth( double wid );};

友元类:

friend class ClassTwo;

请看下面的程序:

#include <iostream>using namespace std;class Box{double width;public:friend void printWidth( Box box );//声明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 main( ){Box box;// 使用成员函数设置宽度box.setWidth(10.0);// 使用友元函数输出宽度printWidth( box );return 0;}

当上面的代码被编译和执行时,它会产生下列结果:

Width of box : 10

七.this指针

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

友元函数没有 this 指针,因为友元不是类的成员。只有成员函数才有 this 指针。

#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 box2){return this->Volume() > box2.Volume();}private:double length;// Length of a boxdouble breadth; // Breadth of a boxdouble height;// Height of a box};int main(void){Box Box1(3.3, 1.2, 1.5); // Declare box1Box Box2(8.5, 6.0, 2.0); // Declare box2if(pare(Box2))//对象Box1调用函数compare(Box2),函数的参数是Box2,所以this指针指向Box1,Box2体积更大,所以函数返回值为0,输出“Box2 is equal to or larger than Box1”。{cout << "Box2 is smaller than Box1" <<endl;}else{cout << "Box2 is equal to or larger than Box1" <<endl;}return 0;}

当上面的代码被编译和执行时,它会产生下列结果:

Constructor called.Constructor called.Box2 is equal to or larger than Box1

八.指向类的指针

一个指向 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;}private:double length;// Length of a boxdouble breadth; // Breadth of a boxdouble height;// Height of a box};int main(void){Box Box1(3.3, 1.2, 1.5); // Declare box1Box Box2(8.5, 6.0, 2.0); // Declare box2Box *ptrBox;// Declare pointer to a class.// 保存第一个对象的地址ptrBox = &Box1;// 现在尝试使用成员访问运算符来访问成员cout << "Volume of Box1: " << ptrBox->Volume() << endl;// 保存第二个对象的地址ptrBox = &Box2;// 现在尝试使用成员访问运算符来访问成员cout << "Volume of Box2: " << ptrBox->Volume() << endl;return 0;}

九.类的静态成员

我们可以使用 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;// 每次创建对象时增加 1objectCount++;}double Volume(){return length * breadth * height;}private:double length;// 长度double breadth; // 宽度double height;// 高度};// 初始化类 Box 的静态成员int Box::objectCount = 0;int main(void){Box Box1(3.3, 1.2, 1.5); // 声明 box1Box 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>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;// 每次创建对象时增加 1objectCount++;}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(void){// 在创建对象之前输出对象的总数cout << "Inital Stage Count: " << Box::getCount() << endl;Box Box1(3.3, 1.2, 1.5); // 声明 box1Box Box2(8.5, 6.0, 2.0); // 声明 box2// 在创建对象之后输出对象的总数cout << "Final Stage Count: " << Box::getCount() << endl;return 0;}

当上面的代码被编译和执行时,它会产生下列结果:

Inital Stage Count: 0Constructor called.Constructor called.Final Stage Count: 2

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。