1.class类 属性--》数据成员 行为--》成员函数 public:private:对象
//class 类名 相当于自己自定义的一个类型,然后在主函数中可以给自己自定义的这个类型
//输入各种各样的值作为它的属性,比如自定义一个类型输入他的身高,体重,名字,性别等
#include<iostream>
using namespace std;
class person
{
public: //属性是指每个对象所内在的本身固有的东西;
//在前面加上public:表示这些内容是公有的(别的函数可以使用这个对象的属性或功能)
public://如果什么都不写,默认是私有的,私有的话就关闭数据权限,别的函数不允许使用
char name[20]; //属性一般是指 数据成员(为对象存储数据)
double height;
double weight;
char sex[10];
//如果在前面加上private:表示私有 一般其他函数不可以引用
double gethigh()//行为一般是指 成员函数 (为实现对象某些功能)
{
return height;//在输入这个对象数据后,当调用这个函数时候,可以返回值
//记住 double类型要和身高类型相同
}
void showhigh() //这个成员函数 显示身高,前面的void返回类型值为空,因为本身这个成员函数就不需要返回任何值
{
cout<<name<<"的身高是:"<<height<<endl;
}
//protected://还没详细学习,可以忽略
//private:
};
int main()
{
person a,b;
cin>>a.name>>a.height>>a.weight>>a.sex; 对象.属性或者行为 相当于引用这个对象的数据或者成员函数
a.showhigh();
cout<<"显示性别:"<<a.sex<<endl; //我为我自己定义的类分配了2个对象 a和b,
//但b我并没有给他赋值
//对象就相当于类型对应的 变量 自己理解 比如说整型 int a,b;这里说的 a,b可以看作2个不同的对象
}
在类的内部(定义类的代码内部),无论成员被声明为 public、protected 还是 private,都是可以互相访问的,没有访问权限的限制。
在类的外部(定义类的代码之外),只能通过对象访问成员,并且通过对象只能访问 public 属性的成员,不能访问 private、protected 属性的成员。
2.关于为什么每个c++都要使用using namespace std;这个问题
我用我最通俗的语言描述
namespace是为了解决C++中的名字冲突而引入的。
什么是名字冲突呢?比如,在文件x.h中有个类MyClass,
在文件y.h中也有个类MyClass,而在文件z.cpp中要同时
引用x.h和y.h文件。显然,按通常的方法是行不能的,
那怎么办呢?引入namespace即可。
这个时候定义x.h中的类MyClass在一个命名空间里,y.h中的类MyClass在另一个命名空间里,
这时候我在z.pp使用他们的类前声明他们分别属于哪个命名空间,我就可以准确的找到他们而不会混淆。
C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
以下内容为网上找的 hex 也是std中的一个指令,可以用来进行十六进制流输出。
由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:
1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下:
std::cout << std::hex<< 3.4<< std::endl;
2、使用using关键字。
using std::cout;
using std::endl;
以上程序可以写成
cout << std::hex<< 3.4<< endl;
3、最方便的就是使用using namespace std;
例如:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
这样命名空间std内定义的所有标识符都有效(曝光)。就好像它们被声明为全局变量一样。那么以上语句可以如下写:
cout << hex<< 3.4<< endl;
3.类外定义
当成员函数较多的时候写在里面会使得这个类的代码非常的乱,我们需要在类里面声明一下存在这个成员函数,具体的功能我们就需要在类外定义
具体实例如下
//class 类名 相当于自己自定义的一个类型,然后在主函数中可以给自己自定义的这个类型
//输入各种各样的值作为它的属性,比如自定义一个类型输入他的身高,体重,名字,性别等
#include<iostream>
using namespace std;
class person
{ public:
char name[20];
double height;
double weight;
char sex[10];
double gethigh();
void showhigh();
};
double person::gethigh()
{
return height;
}
void person:: showhigh()
{
cout<<name<<"的身高是:"<<height<<endl;
}
int main()
{
person a,b;
cin>>a.name>>a.height>>a.weight>>a.sex;
a.showhigh();
cout<<"显示性别:"<<a.sex<<endl;
}
类内声明 double gethigh();
void showhigh();
类外定义
double person::gethigh()
{
return height;
}
void person:: showhigh()
{
cout<<name<<"的身高是:"<<height<<endl;
}
我按照个人理解 ::可以看成是属于的意思 person::gethigh() 这个gethigh是属于person这个类的 包括前面所讲的命名空间 std::cout 中cout这个是属于std这个标准命名空间的。
4.构造函数:它的名字和类名相同,没有返回值,不需要用户显式调用(用户也不能调用),而是在创建对象时自动执行。这种特殊的成员函数就是构造函数(Constructor)。
在创建类的时候,若不给这个类设置构造函数,我们的这个类默认为无参构造函数。
在主函数中声明 也是直接 person a;相当于设置了无参的构造函数
类名(这是个构造函数不含参)具体内容也没有
{
}
,但是如果是设置了含参的构造函数
person(double x,double y)//含有2个参数
{
height=x;weight=y;
}
在主函数中定义类时候 类的结构要和构造函数相同。含参个数不限
person a(177,140)
5.析构函数
析构函数于构造函数相对应,构造函数是对象创建的时候自动调用的,而析构函数就是对象在销毁的时候自动调用的的
特点:
1)构造函数可以有多个来构成重载,但析构函数只能有一个,不能构成重载
2)构造函数可以有参数,但析构函数不能有参数
3)与构造函数相同的是,如果我们没有显式的写出析构函数,那么编译器也会自动的给我们加上一个析构函数,什么都不做;如果我们显式的写了析构函数,那么将会覆盖默认的析构函数
4)在主函数中,析构函数的执行在return语句之前,这也说明主函数结束的标志是return,return执行完后主函数也就执行完了,就算return后面还有其他的语句,也不会执行的
仔细阅读以上代码会发现,首先定义的是ob1不含参,ob2含2个参,结尾最后输出的析构函数先是ob2的析构函数,后输出ob1的析构函数。观察发现它的特点是先进后出,后进先出。每个构造函数,如果我们不自定义,系统都会自动为它分配存储析构函数。本代码中我们自定义析构函数覆盖原析构函数,然后输出“析构函数”以便观察。
6.拷贝构造函数
7.函数重载
在同一个作用域中,如果有多个函数的名字相同,但是形参列表不同(参数类型不同或参数个数不同),返回值类型可同也可不同,我们称之为重载函数。重载的函数是通过形参列表区分的,与返回值类型无关。
int add(int a, int b)
{
return a + b;
}
float add(float a, int b)//每个参数的类型不同 当输入不同类型的数据时候,编辑器会据此选择不同的同名函数并进入
{
return a + b;
}
float add(int a, float b)
{
return a + b;
}
float add(float a,float b)
{
return a + b;
}
关于一些需要注意到的是 函数中参数的传递顺序是从右往左赋值
这里的20先赋给y或者r,此时编辑器不知道调用哪个函数 是r=20,还是y=20;所以就报错
不确定计算机如何进行数据类型转换,因此我们得使用类型的强制类型转换
如果把函数重载和构造函数联系在一起
8.强制类型转换
转换数据类型(需要转换的数字或变量)
int(5.56) 将5.56强制转换为常整型 转换后为5
double(5)将5强制转换为double型 转换后为5 ,它是double型,但c++不显示后面数字
9.对象指针
10.向函数传递对象
以下为3个具体代码实例
11.静态数据成员
这个是我们可爱的c++老师
回归正题
11.静态成员函数
看题目
12.友元函数