C++类和对象详解
发布网友
发布时间:2022-04-23 20:54
我来回答
共2个回答
热心网友
时间:2023-07-02 11:33
类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。类成员函数是类的一个成员,它可以操作类的任意对象,可以访问对象中的所有成员。
class Box
{
public:
double length; // 长度
double breadth; // 宽度
double height; // 高度
double getVolume(void);// 返回体积
};
成员函数可以定义在类定义内部,或者单独使用范围解析运算符 :: 来定义。在类定义中定义的成员函数把函数声明为内联的,即便没有使用 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(); // 调用该对象的成员函数
一个类可以有多个 public、protected 或 private 标记区域。每个标记区域在下一个标记区域开始之前或者在遇到类主体结束右括号之前都是有效的。成员和类的默认访问修饰符是 private。
class Base {
public:
// public members go here
protected:
// protected members go here
private:
// private members go here
};
公有成员在程序中类的外部是可访问的。您可以不使用任何成员函数来设置和获取公有变量的值。就是说你可以直接用对象+“.”(点运算符)的方式来为公有变量赋值。
私有成员变量或函数在类的外部是不可访问的,甚至是不可查看的。只有类和友元函数可以访问私有成员。(这个和Java不一样,Java类中默认是public)
默认情况下,类的所有成员都是私有的。
实际操作中,我们一般会在私有区域定义数据,在公有区域定义相关的函数,以便在类的外部也可以调用这些函数。这个方式确实好,有点里应外合的感觉。
保护成员变量或函数与私有成员十分相似,但有一点不同,保护成员在派生类(即子类)中是可访问的。
下面的实例与前面的实例类似,在这里 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;
}
类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。
构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。
默认的构造函数没有任何参数,但如果需要,构造函数也可以带有参数。这样在创建对象时就会给对象赋初始值。
使用初始化列表来初始化字段:
Line::Line( double len): length(len)
{
cout << "Object is being created, length = " << len << endl;
}
上面的语法等同于如下语法:
Line::Line( double len)
{
cout << "Object is being created, length = " << len << endl;
length = len;
}
假设有一个类 C,具有多个字段 X、Y、Z 等需要进行初始化,同理地,您可以使用上面的语法,只需要在不同的字段使用逗号进行分隔,如下所示:
C::C( double a, double b, double c): X(a), Y(b), Z(c)
{
....
}
类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
下面的实例有助于更好地理解析构函数的概念:
#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
可见构造函数与析构函数表面上是一个“~”的差别,其实作用恰恰相反,一个生成,一个回收。
拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:
3.拷贝构造函数调用的三种形式
3.1.一个对象作为函数参数,以值传递的方式传入函数体;
3.2.一个对象作为函数返回值,以值传递的方式从函数返回;
3.3.一个对象用于给另外一个对象进行初始化(常称为复制初始化)。
总结:当某对象是按值传递时(无论是作为函数参数,还是作为函数返回值),编译器都会先建立一个此对象的临时拷贝,而在建立该临时拷贝时就会调用类的拷贝构造函数。
如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。该构造函数完成对象之间的位拷贝。(位拷贝又称浅拷贝,后面将进行说明。)自定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。拷贝构造函数的最常见形式如下:
classname (const classname &obj) {
// 构造函数的主体
}
在这里,obj 是一个对象引用,该对象是用于初始化另一个对象的。
在某些状况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。事实上这就要用到深拷贝了,要自定义拷贝构造函数。(这一段其实很好理解)
深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝
浅拷贝资源后在释放资源的时候会产生资源归属不清的情况导致程序运行出错。一定要注意类中是否存在指针成员。
友元函数并不是成员函数。友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。
如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend,如下所示:
class Box
{
double width;
public:
double length;
friend void printWidth( Box box );
void setWidth( double wid );
};
声明类 ClassTwo 的所有成员函数作为类 ClassOne 的友元,需要在类 ClassOne 的定义中放置如下声明:
friend class ClassTwo;
C++ 内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。
对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编译器需要重新更换一次所有的代码,否则将会继续使用旧的函数。
如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字 inline,在调用函数之前需要对函数进行定义。如果已定义的函数多于一行,编译器会忽略 inline 限定符。
在类定义中的定义的函数都是内联函数,即使没有使用 inline 说明符。
一个指向 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 main(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 指针。您可以使用静态成员函数来判断类的某些对象是否已被创建。
热心网友
时间:2023-07-02 11:34
#include using namespace std;class myclass{private:int number;static int obj_num;public:myclass() //默认构造函数{number = 0;cout
类和对象与c 语言的结构体,有啥区别呢
简单的说,类和对象是对一件事物的抽象,可以有自己的访问方式(如public),成员变量,成员函数,继承和被继承这样的关系。而结构体,只是用来表示一个结构的,它有成员变量,成员函数(c++后来加入的……)。但是没有访问方式和继承这样的关系,它只是用于表示一种数据结构。
vlookup函数匹配数据的使用方法
Excel一键自动匹配,在线免费vlookup工具,3步完成!Excel在线免费vlookup工具,点击9步自动完成vlookup匹配,无需手写公式,免费使用!
能帮我解释下才c语言中数据类型,表达式,运算符,类和对象它们的...
运算符,就是 + - X ÷ 这些 符号表示运算的 这个应该好理解,编程中还有别的运算符.你都先这么理解就好了.类 这个比较难讲明白. 它是一个抽象的概念.. 就相当于 自行车 汽车 轮船 火车 他们都属于交通工具.. 那么交通工具 就是一个类.. 然后 自行车 汽车什么的 就是它的对象.不知道你...
Java里“类”和“对象”定义分别是什么?我学过C语言,可以用里面的东西解...
对象:表示一个独立的个体,每个对象拥有自己独立的属性,依靠属性来区分不同对象。类和对象的区别:类是对象的模板,对象是类的实例。类只有通过对象才可以使用,而在开发之中应该先产生类,之后再产生对象。类不能直接使用,对象是可以直接使用的 ...
省考a类b类c类什么意思
在省考中,A类、B类、C类岗位是根据不同的招录岗位而设定的分类。简单来说,它们代表了不同的岗位性质与难度。其中,A类通常是省直机关岗位,B类岗位指的是有专业限制的岗位,而C类主要是乡镇机关岗位。相对来说,A类岗位是最难考的,其考试内容与题目难度均高于B类和C类。二、年龄与学历条件 对于...
城市低保b类和c类哪个好
1、b类为较为困难的。即家庭主要成员为老、弱、病、残等靠自身努力难以改变贫困状况的家庭,需要长期享受低保待遇的家庭。2、c类为较为短期的保障对象。即家庭主要成员有劳动能力,比较年轻、身体较好、有就业潜力的各类待岗失业人员,属隐性就业问题突出、就业几率大的家庭,保费最少。
面向对象编程中关于类的行为的理解?
ATM类的LoginAccount行为:从UI获取一个name和一个password,new一个Account对象,set好这个对象的name和password属性,然后调用这个对象的Login行为。再根据调用的结果作出反应。---神马的分割线再次出现--- 总而言之,我觉得你的问题主要出在混淆了“类”和“对象”的区别 从你会说出“账户类应该就是一...
python中class类的用法(python中class)
1.类变量:能够通过类名或者object的self来访问到,在类的内部和外部均可达,比如class_var_1 2.对象变量:可以通过对象的self来使用的变量,通过constructor一路走向去的的self初次被赋值的变量都会成为对象变量,比如object_var_1,object_var_2,object_var_3,object_var_4 3.内部变量:可以在函数中...
c语言详解sizeof
对于联合类型,sizeof 是其最大字节成员的字节数;对于结构类型,则是其成员类型的总字节数,包括填充字节在内。sizeof 的结果类型为 size_t,定义在头文件中为 typedef unsigned int size_t;。该类型确保能容纳实现中最大对象的字节大小。ANSI C 定义字符类型为 1 字节,其他类型大小依赖于实现。当...
...不懂··· 关于什么类啊 对象的~求详细解释
void stud::setscore(int sc) // 修改 函数类型,与类定义一致,增加stud::, 表示是 stud的成员函数 { score=sc; } void stud::inscore(){ cin>>score; } // 去掉s. , 下同。void stud::getscore(){ cout<<score<<endl;} // 建议不在类的 成员函数中 使用 CIN,COUT等,...
有关类和对象的说法正确的是 。 A. 类是对象的一个实例 B. 任何一个...
B、任何一个对象只能属于一个具体的类。类的实质是一种引用数据类型,类似于byte、short、int(char)、long、float、double等基本数据类型,不同的是它是一种复杂的数据类型。因为它的本质是数据类型,而不是数据,所以不存在于内存中,不能被直接操作,只有被实例化为对象时,才会变得可操作。