c++基础学习(07)--(类)
文章目录
- 目录
- 类与对象
- 1.类成员函数
- 2.类访问修饰符
- 3.构造函数与析构函数
- 4.拷贝构造函数
- 5. 友元函数
- 6.内联函数
- 7.this指针
- 8.指向类的指针
- 9.类的静态成员
目录
类与对象
#include <iostream>using namespace std;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;// 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;return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Box1 的体积:210
Box2 的体积:1560
需要注意的是,私有的成员和受保护的成员不能使用直接成员访问运算符 (.) 来直接访问.
1.类成员函数
#include <iostream>
#include <limits>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
2.类访问修饰符
公有成员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
保护成员变量或函数与私有成员十分相似,但有一点不同,保护成员在派生类(即子类)中是可访问的。
在下一个章节中,您将学习到派生类和继承的知识。现在您可以看到下面的实例中,我们从父类 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;
}
#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;
}
10
1
sh: 1: pause: not found
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;
}
3.构造函数与析构函数
#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
类的析构函数
类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
下面的实例有助于更好地理解析构函数的概念:
#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
4.拷贝构造函数
#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. 友元函数
#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
6.内联函数
#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
7.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
8.指向类的指针
一个指向 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 = &Box1;; // Declare pointer to a class.// 保存第一个对象的地址// 现在尝试使用成员访问运算符来访问成员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
9.类的静态成员
我们可以使用 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
#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++基础学习(07)--(类)相关推荐
- 零基础学python实战-零基础学习python_类和对象(36-40课)
今天我们开始学习面向对象的知识咯,之前我对面向对象也学的懵懵的,因为感觉知道好像又不是特别清楚,接下来我们一起来学习类和对象吧.零基础的课程我都是看小甲鱼的视频学的,没基础的可以去这个网址下载视频学习 ...
- java string类方法_Java基础学习——String类及其方法
String类概述 该类被final修饰,无子类,不可被复写.创建的对象一旦初始化,其内容不可被改变. String类复写了Object类中的equals()定义了自己的独特内容,该方法用于判断字符串 ...
- Python基础学习:类语法规则
[类] 一.定义方式: class 类名(object): 二.调用方式: 1.类名() 2.对象 = 类名() #当一个变量 等于 一个类名() #时它就叫对象 三.方法: 1.公有方法() #方 ...
- 尚硅谷Java基础学习--常用类部分例题解答(仅使用String类方法)
以下为不借助StringBuffer等类的方法,直接使用String类方法及算法实现: No.1 public class Test1010 {public static void main(Stri ...
- C++类基础学习(1)
类基础学习(C++) 题录:作者是个博客小萌新,C++已学习了一段时间,做过几个小项目(VS+qt的),但都很简单,在深入学习时,发现但个人缺少系统的总结以及整体知识框架的构建,所以准备通过CSDN这 ...
- java虚拟机预先加载哪些类_Java虚拟机JVM学习02 类的加载概述
Java虚拟机JVM学习02 类的加载概述 类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对 ...
- Java学习07–前端基础之CSS
Java学习07–CSS基础 1.CSS介绍 1.1.发展史 css1.0 基本 css2.0 div(块)+css html与css结构分离的思想网页变简单 css2.1 浮动,定位 css3.0 ...
- Python基础学习-Python中最常见括号()、[]、{}的区别 2015-08-13 07:54 by xuxiaoxiaoxiaolu, 1138 阅读, 0 评论, 收藏, 编辑 Pytho
Python基础学习-Python中最常见括号().[].{}的区别 2015-08-13 07:54 by xuxiaoxiaoxiaolu, 1138 阅读, 0 评论, 收藏, 编辑 Pytho ...
- TS基础2(类)-学习笔记
文章目录 TS基础2(类)-学习笔记 class类 类的继承 修饰符 类的类型.实现接口 TS基础2(类)-学习笔记 class类 //类 class//首字母大写//类(Class):定义了一件事物 ...
- 列表怎么有限的初始化为零_《零基础学习Android开发》第五课 类与面向对象编程1-1...
视频:<零基础学习Android开发>第五课 类与面向对象编程1-1 类的定义.成员变量.构造方法.成员方法 一.从数据与逻辑相互关系审视代码 通过前面的课程,我们不断接触Java语言的知 ...
最新文章
- Java删除文件及其子文件、文件夹
- vs2017中编译提示一些系统头文件没有找到
- android 版本权限差别,android apk 的root 权限和USB adb 权限的区别
- [ExtJs6] 环境搭建及创建项目
- window系统服务器改名,微软:不会将 Windows Server 改名为 Microsoft Server 系统
- 使用Docker部署SpringBoot
- python爬虫入库到帝国cms_帝国小说连载系统合理利用第三方云爬虫缓存章节内容...
- 《算法第4版》与《算法导论》比较
- springboot获取视频时长以及截取视频第一帧
- 小白如何打造一个基础的留言板网站(二)
- 有源码如何搭建网站(从零开始搭建教程)
- 推荐两个在线代理服务器
- 基于双目视觉的非标机械臂的空间定位流程(未完待续)
- 用R语言进行筛选数据
- 乐学偶得python视频_乐学偶得 - 课程
- 坚持学习100天:Typedef 重(chong)定义还是重(zhong)定义呢?
- 流程图讲解_流程图+地图题小作文练习,详细讲解+精选范文!!
- 关于a21A11+a22A12+a23A13=0的证明
- c语言微信昵称大全女生优雅经典的,女生优雅的微信昵称
- python天天向上和天天向下代码解析_天天向上的力量python(举一反三)
热门文章
- python生成多个列表_python生成多个只含0,1元素的随机数组或列表(代码)
- 《计算机应用》实践考核,《管理系统中计算机应用》实践性环节考核方案
- activexobject对象不能创建_Oracle数据库用户管理之系统权限和对象权限
- excel办公常用的宏_让领导看傻!精美168套办公常用excel模板免费领
- 数据结构与算法(C#版)第二章 C#语言与面向对象技术(下)V1.0
- matlab lmi 定义一个任意方阵,matlab中LMI应用说明
- 【GUI开发】图像处理类软件的浏览功能实现模型
- 算法 - 堆排序(大顶堆、小顶堆)
- CCNA-网络常用工具介绍篇
- 【机器学习】 - CNN