当前位置: 首页 > news >正文

惠州最专业的网站建设公司/百度有哪些app产品

惠州最专业的网站建设公司,百度有哪些app产品,wordpress 文章归档设置,下载类网站怎么做C 类 & 对象 一、C 类 & 对象 C 在 C 语言的基础上增加了面向对象编程,C 支持面向对象程序设计。类是 C 的核心特性,通常被称为用户定义的类型。 类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。类中的数据和方法…

@C++ 类 & 对象

一、C++ 类 & 对象

C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心特性,通常被称为用户定义的类型。

类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员。函数在一个类中被称为类的成员

二、C++ 类定义

定义一个类,本质上是定义一个数据类型的蓝图。这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作
在这里插入图片描述
类定义是以关键字 class 开头,后跟类的名称。类的主体是包含在一对花括号中。类定义后必须跟着一个分号或一个声明列表。例如,我们使用关键字 class 定义 Box 数据类型,如下所示:

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

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

三、定义 C++ 对象

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

Box Box1;          // 声明 Box1,类型为 Box
Box 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 main( )
{Box Box1;        // 声明 Box1,类型为 BoxBox Box2;        // 声明 Box2,类型为 BoxBox Box3;        // 声明 Box3,类型为 Boxdouble 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


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

五、类 & 对象详解

5.1 类成员函数

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

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

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

成员函数可以定义在类定义内部,或者单独使用范围解析运算符 :: 来定义。在类定义中定义的成员函数把函数声明为内联的,即便没有使用 inline 标识符。所以您可以按照如下方式定义 getVolume() 函数:

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();  // 调用该对象的成员函数

我们使用上面提到的概念来设置和获取类中不同的成员的值:

#include <iostream>using namespace std;class Box
{public:double length;         // 长度double breadth;        // 宽度double height;         // 高度// 成员函数声明double getVolume(void);void setLength( double len );void setBreadth( double bre );void setHeight( double hei );
};// 成员函数定义
double Box::getVolume(void)
{return length * breadth * height;
}void Box::setLength( double len )
{length = len;
}void Box::setBreadth( double bre )
{breadth = bre;
}void Box::setHeight( double hei )
{height = hei;
}// 程序的主函数
int main( )
{Box Box1;                // 声明 Box1,类型为 BoxBox Box2;                // 声明 Box2,类型为 Boxdouble volume = 0.0;     // 用于存储体积// box 1 详述Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0);// box 2 详述Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0);// box 1 的体积volume = Box1.getVolume();cout << "Box1 的体积:" << volume <<endl;// box 2 的体积volume = Box2.getVolume();cout << "Box2 的体积:" << volume <<endl;return 0;
}

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

5.2 类访问修饰符

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

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

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

公有(public)成员
公有成员在程序中类的外部是可访问的。您可以不使用任何成员函数来设置和获取公有变量的值,如下所示:

#include <iostream>using namespace std;class Line
{public:double length;void setLength( double len );double getLength( void );
};// 成员函数定义
double Line::getLength(void)
{return length ;
}void Line::setLength( double len )
{length = len;
}// 程序的主函数
int main( )
{Line line;// 设置长度line.setLength(6.0); cout << "Length of line : " << line.getLength() <<endl;// 不使用成员函数设置长度line.length = 10.0; // OK: 因为 length 是公有的cout << "Length of line : " << line.length <<endl;return 0;
}

Length of line : 6
Length of line : 10

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

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

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

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

#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;
}

Length of box : 10
Width of box : 10

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;
}

Width of box : 5

继承中的特点
有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 成员可以被派生类访问。

public 继承

#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 : 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;
}

protected 继承

#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 : 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;
}

private 继承

#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;
}

5.3 构造函数 & 析构函数

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

构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 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 created
Length 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 = 10
Length of line : 10
Length of line : 6

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

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©
{

}

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

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

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

#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 created
Length of line : 6
Object is being deleted

5.4 C++ 拷贝构造函数

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

通过使用另一个同类型的对象来初始化新创建的对象。

复制对象把它作为参数传递给函数。

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

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

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

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

#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;
}

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

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

#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;
}

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

5.5 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 main( )
{Box box;// 使用成员函数设置宽度box.setWidth(10.0);// 使用友元函数输出宽度printWidth( box );return 0;
}

Width of box : 10

5.6 C++ 内联函数

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

对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编译器需要重新更换一次所有的代码,否则将会继续使用旧的函数。

如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字 inline,在调用函数之前需要对函数进行定义。如果已定义的函数多于一行,编译器会忽略 inline 限定符。

在类定义中的定义的函数都是内联函数,即使没有使用 inline 说明符。

下面是一个实例,使用内联函数来返回两个数中的最大值:

#include <iostream>using namespace std;inline int Max(int x, int y)
{return (x > y)? x : y;
}// 程序的主函数
int main( )
{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

5.7 C++ 中的 this 指针

在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。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 box){return this->Volume() > box.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(Box1.compare(Box2)){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

5.8 C++ 中指向类的指针

一个指向 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;
}

Constructor called.
Constructor called.
Volume of Box1: 5.94
Volume of Box2: 102

5.9 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;// 每次创建对象时增加 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: 0
Constructor called.
Constructor called.
Final Stage Count: 2

菜鸟教程,学习记录

相关文章:

C++基础了解-20-C++类 对象

C 类 & 对象 一、C 类 & 对象 C 在 C 语言的基础上增加了面向对象编程&#xff0c;C 支持面向对象程序设计。类是 C 的核心特性&#xff0c;通常被称为用户定义的类型。 类用于指定对象的形式&#xff0c;它包含了数据表示法和用于处理数据的方法。类中的数据和方法…...

多态与虚(函数)表

前言续接上回&#xff08;继承&#xff09;&#xff0c;我们了解了继承是如何通过虚基表&#xff0c;来解决派生类和父类有相同的成员变量的情况&#xff0c;但是类和对象中可不只有成员变量&#xff0c;如果成员函数也有同名&#xff0c;更或者如果我们想在访问不同情况&#…...

云舟案例︱视频孪生技术赋能城市安全综合管理场景,提升城市数智化水平

随着城市化发展进程的加快&#xff0c;人口不断膨胀&#xff0c;社会安全隐患等问题日益突出&#xff0c;成为困扰城市建设与管理的重要难题。针对各类社会治安突出问题&#xff0c;城市管理部门积极推进城市信息化建设&#xff0c;视频监控等各类信息化采集手段为城市数字化管…...

OpenFOAM 自定义gcc和openmpi安装

Compile Logs 编译很多次了但是好久不编还是会容易遗漏细节步骤&#xff0c;谨以为记。 使用自己编译的编译器和openmpi而不是系统自带的 库来完成对OF 的编译 依赖包安装 编译 GCC 编译 openmpi 编译OF 1依赖包安装 先 sudo apt-get install update当然&#xff0c;然后安…...

2023年3.8女神节买台灯怎么挑选?台灯用什么样的比较好

最近女神节&#xff0c;祝广大女性朋友们节日快乐啊。娱乐之余&#xff0c;一些实用的东西也是非常适合作为礼物送给女性朋友哦&#xff0c;台灯就是其中一个不错的选择。 台灯作为一种智能家居产品&#xff0c;不仅可见点缀卧室房间装饰&#xff0c;晚上的时候开启小范围照明&…...

近亿美元:人工心脏龙头永仁心医疗完成超大额A轮融资

近日&#xff0c;永仁心医疗器械有限公司&#xff08;以下简称“永仁心医疗”&#xff09;完成近一亿美元A轮融资&#xff0c;由北京科兴中维生物技术有限公司&#xff08;SINOVAC科兴&#xff09;领投&#xff0c;太平&#xff08;深圳&#xff09;医疗健康产业私募股权投资基…...

群智能优化计算中的混沌映射

经实验证明&#xff0c;采用混沌映射产生随机数的适应度函数值有明显提高&#xff0c;用混沌映射取代常规的均匀分布的随机数发生器可以得到更好的结果&#xff0c;特别是搜索空间中有许多局部解时&#xff0c;更容易搜索到全局最优解&#xff0c;利用混沌序列进行种群初始化、…...

【LeetCode】剑指 Offer 25. 合并两个排序的链表 p145 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/ 1. 题目介绍&#xff08;25. 合并两个排序的链表&#xff09; 输入两个递增排序的链表&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 【测试用例】&#xf…...

如何应对危害机房安全的这几个常见要素?

随着现代化进程的推进&#xff0c;各行业对计算机的依赖性日益增高&#xff0c;计算机系统已经成为业务系统的重要组成部分。 在这种情况下&#xff0c;一旦机房设备出现故障&#xff0c;就会影响机房的正常运行&#xff0c;造成严重后果。尤其是银行、证券、海关等需要实时数据…...

【bug】antd全局的主题色样式被覆盖,被修改为`antd`默认的主题色

背景&#xff1a; 项目本身修改了主题色,配置如下: // umi配置文件 export default {theme: {primary-color: #2F54EB, // 全局主色}, };需要对图片上传组件做封装,并在项目中统一引用,如下 import { TdsUpload } from tdsComponents;环境信息 node tiandstiandsdeMacBook…...

MySQL DDL表操作【入门到精通】

目录 一、查询创建 1、查询当前数据库所有表 2、查看指定表结构 3、查询指定表的建表语句 4、创建表结构 二、数据类型 1、数值类型 2、字符串类型 3、日期时间类型 三、表操作-案例 设计一张员工信息表&#xff0c;要求如下&#xff1a; 对应的建表语句如下&#…...

《MySQL系列-InnoDB引擎28》表-约束详细介绍

约束 1 数据完整性 关系型数据库系统和文件系统的一个不同点是&#xff0c;关系数据库本身能保证存储数据的完整性&#xff0c;不需要应用程序的控制&#xff0c;而文件系统一般需要在程序端进行控制。当前几乎所有的关系型数据库都提供约束(constraint)机制&#xff0c;该机制…...

使用docker部署宝塔环境

经常需要部署lnmp环境&#xff0c;宝塔是一个不错的选择&#xff0c;包括安装各种插件&#xff0c;添加网站&#xff0c;设置定时任务等都非常方便。这次使用docker来部署。 拉取centos镜像 docker pull centos启动容器 1.-p端口映射&#xff0c;-d后台运行 2. 文件夹做一下映…...

ORB_SLAM2+kinect稠密建图

下载代码&#xff1a;https://github.com/gaoxiang12/ORBSLAM2_with_pointcloud_map 运行代码&#xff1a; 解压代码后&#xff0c;删掉作者自己编译的build文件夹&#xff08;下面三个都删除&#xff09;&#xff1a; ~/ORB_SLAM2_modified/build, ~/ORB_SLAM2_modified/T…...

mujoco安装及urdf转xml方法记录

参考 mujoco210及mujoco-py安装 下载适用于Linux或 OSX的 MuJoCo 2.1 版二进制文件 。 将mujoco210的下载的目录解压到~/.mujoco/mujoco210路径下. 注意&#xff1a;如果要为包指定非标准位置&#xff0c;请使用环境变量MUJOCO_PY_MUJOCO_PATH。 验证是否安装成功&#xff08…...

Visual Studio 2019 + Qt 项目版本信息新增到资源以及通过代码读取资源存储的版本信息

文章目录前言一、如何在VisualStudio2019中新增项目版本信息二、在程序中调用项目版本信息1.引入库version.lib1.1.通过vs自带的属性页引入库1.2.手动引入库2.新增版本信息读取类3.调用类获取信息总结前言 本文主要讲述如何在Visual Studio 2019 以及Qt结合的开发项目中&#…...

裸辞两个月还能不能找到工作?亲身经历告诉你结果·····

这是我在某论坛看到的一名网友的吐槽&#xff1a; 软件测试四年&#xff0c;主要是手动测试&#xff08;部分自动化测试和性能测试&#xff0c;但是用的是公司内部自动化工具&#xff0c;而且我自动化方面是弱项。&#xff09;现在裸辞两个月了&#xff0c;面试机会少而且面试…...

2023华为面试真题

【华为】面试真题&#xff1a; 面试前需要准备&#xff1a; 1. Java 八股文&#xff1a;了解常考的题型和回答思路&#xff1b; 2. 算法&#xff1a;刷 100-200 道题&#xff0c;记住刷题最重要的是要理解其思想&#xff0c;不要死记硬背&#xff0c;碰上原题很难&#xff0…...

【C++】C++11新特性——基础特性

文章目录一、列表初始化1.1 {}初始化1.2 initializer_list类型二、类型推导2.1 auto2.2 auto注意事项2.3 decltype三、新增与改进3.1 nullptr3.2 范围for3.3 array3.4 forward_list3.5 unordered系列3.6 final与override一、列表初始化 1.1 {}初始化 C11 引入了一个新的初始化…...

Mac 遇到pip: command not found问题的解决

Mac 遇到pip: command not found问题的解决在学习Playwright时候&#xff0c;需要下载相关依赖Playwright 是专门为满足端到端测试的需要而创建的。Playwright 支持所有现代渲染引擎&#xff0c;包括 Chromium、WebKit 和 Firefox。在 Windows、Linux 和 macOS 上进行本地测试或…...

[ 云计算 | Azure ] Episode 03 | 描述云计算运营中的 CapEx 与 OpEx,如何区分 CapEx 与 OpEx

正常情况如果你不是会计&#xff0c;或者对钱相关的数字比较敏感的财务&#xff0c;本文的一些东西你不会接触的&#xff0c;但是最为云架构或者云运营&#xff0c;你可能会遇到如何采购亦或者估算的我成本和运营成本等等&#xff0c;所以本文的一些知识点就需要进行一定的了解…...

STM32F103R8T6 SPWM实现正弦波输出

前言 PWM合成正弦波&#xff0c;原理什么的不详细说了&#xff0c;概括一下就是 PWM有效面积的积分 正弦波的有效面积。PWM的频率越快&#xff0c;细分的越多&#xff0c;锯齿也就越不明显。 做法是&#xff1a;首先利用正弦波取点软件&#xff0c;取点1000个&#xff0c;生…...

Oracle 11g创建和删除数据库实例

一、创建数据库实例 1.点击“开始” -> “Oracle -OraDb11g_home1” -> “Database Configuration Assistant” 2.点击“下一步” 3.选择“创建数据库”&#xff0c;点击“下一步” 4.默认设置&#xff0c;不用更改&#xff0c;直接点击“下一步” 5.填写要创建的“实例…...

MySQL(四)视图、存储过程、触发器

视图、存储过程、触发器视图检查选项视图的更新存储过程存储过程基本语法变量系统变量用户自定义变量局部变量if判断参数casewhile循环repeat循环loop循环cursor游标handler条件处理程序存储函数触发器视图 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据…...

在 Ubuntu 下编写 C++

在 Ubuntu 下编写 C 在 Ubuntu 上面编写 C&#xff0c;本章节内容主要介绍在 Ubuntu 在终端窗口下使用 vi/vim 编辑一 个 C源文件。通过编写最简单的示例“Hello,World&#xff01;”。带领大家学习如何在 Ubuntu 终端下编 辑和编译 C。这里要求大家会在 Ubuntu 上使用 vi/vim…...

Linux主要目录的意思

Linux目录的意思 文章目录Linux目录的意思bin目录&#xff08;命令目录&#xff09;&#xff1a;二进制目录&#xff0c;二进制是可以直接执行的机器码&#xff0c;里面存放着可以执行的命令&#xff1b;bin目录右下角有个箭头类似于Windows的快捷方式 sbin目录&#xff1a;系…...

启动golang项目编译的exe可执行文件获取windows管理员权限(UAC)

背景&#xff1a; go代码启动以后里面涉及到修改ip地址等操作&#xff0c;需要管理员权限。打包好的exe文件双击执行默认是没有管理员权限的&#xff0c;那么修改ip就会提示需要管理员权限。 解决方法1&#xff1a;右键以管理员权限运行exe文件 解决方法2&#xff1a;编译exe…...

Springboot怎么快速集成Redis?

前言其实在Springboot中集成redis是一个非常简单的事情&#xff0c;但是为什么要单独输出一篇文章来记录这个过程呢&#xff1f;第一个原因是&#xff0c;我记性不是太好&#xff0c;这次把这个过程记录下&#xff0c;在新的项目搭建的时候或者需要在本地集成redis做一些其他相…...

COM技术简单介绍

COM (Component Object Model) 是一种面向对象的编程技术&#xff0c;它在 Windows 操作系统中广泛使用。COM 提供了一种标准的方法来创建和使用可重用的软件组件&#xff0c;这些组件可以通过不同的编程语言和应用程序进行访问和使用。 COM 技术的主要特点包括&#xff1a; 组…...

NetworkMiner网络取证分析工具(26)

预备知识 NetworkMiner是一款windows平台下开放源代码的网络取证分析工具&#xff0c;同时也是一款比较好的协议分析工具&#xff0c;它通过数据包嗅探或解析PCAP 文件能够检测操作系统&#xff0c;主机名和网络主机开放的端口。 除了能够进行基本的数据包抓取分析N…...