补VC基础


——————————————–static—————————————–

静态成员是解决同一个类中不同对象之间的数据和函数共享问题。静态成员是类的所有对象共享的成员,而不是某个对象的成员,他在对象中不占用存储空间。静态成员分为静态数据成员和静态成员函数。

一.静态数据成员

说明:
1.声明:

static <类型> <静态成员>
//如 static int total;

在类的声明中(h文件)仅仅是对静态数据成员进行声明,而不能进行初始化。
2.初始化:

<类型>  <类名> ::<静态成员> = <> 
//如 int Student::total=0;

静态数据成员要实际分配地址空间,由于在程序开始时静态数据成员就必须存在,一般在类的实现部分(cpp文件)进行初始化,通常在开头定义。
3.类外访问:

<类名>::<静态成员>
//如 cout<<"显示学生总的个数"<<Student::total<<endl;
常规法:成员访问符.
//如 cout<<"显示学生总的个数"<<s1.total<<endl;

静态数据成员不属于任何一个对象,只能通过类名对他进行访问,他被所有Student类的对象共享。
这表示当我们建立两个对象s1,s2后,total既不是对象s1也不是对象s2的一部分,他不依赖与任何对象,所有的对象都共享他。因为在对象空间中没有静态数据成员,他的空间不会随着对象的产生而分配(他的空间分配不在类的构造函数里完成),或随着对象的消失而回收(他的空间回收也不在类的析构函数里完成)。

类内访问:用类的成员函数即可(常规法)。

二.静态成员函数
1.其他特性跟静态成员函数相同。
2.静态成员函数没有this指针,所以在静态成员函数中隐式或者显式引用这个指针都会导致编译错误。所以静态成员函数不能引用非静态数据成员,只能访问静态成员(这包括静态数据成员和静态成员函数)。


———————————-new and delete ————————————

动态内存分配:

堆是动态内存分配的,允许程序在运行时申请某个大小的存储单元。
在堆里用分配内存new和释放空间delete。

三.new

<指针变量名> =new <类型>;
//或<指针变量名> =new <类型>[<元素个数>];

四.delete

delete <指针变量名>;
#include "iostream"
using namespace std;
/*****************************************************************************
using namespace是预编译指示,表示using指示符要用到名字空间std的标识符。
std是标准名字空间名,在标准头文件里面声明的函数、对象和类模板等名字都声明在std里面。
所以要使用"iostream"头文件里面的标识符,比如下面的数据流输入输出等,必须先进行预编译指示。
关于名字空间namespace的说明见google。
******************************************************************************/

int main()
{
    int *array,arraysize;
    cout<<"please input a number of array:";
    cin>>arraysize;
    if((array=new int[arraysize])==NULL)          //判断申请空间是否成功
    {
        cout<<"can't allocate memory,terminating.";
        exit(1);
    }
    for(int count=0;count<arraysize;count++)
    {
        array[count]=count*2;
        cout<<array[count]<<'\t';   
    }
    cout<<endl;
    delete []array;                    //删除array所指向的连续存储空间
    system("PAUSE");
}
#include "iostream"

/**********************************************************************
关于类Box的声明和定义代码省略
Box类里面含有构造函数的重载:分别是Box()和Box(int h,int w,int l)
**********************************************************************/

int main()
{
    Box *pbox1=new Box;
    cout<<"The volume of box1 is "<<pbox1->volume()<<endl;
    delete pbox1;

    Box *pbox2=new Box(15,30,25);
    cout<<"The volume of box2 is "<<(*pbox2).volume()<<endl;
    delete pbox2;

    return 0;
}

注释:
1.使用new不但可以建立静态存储空间,而且还可以建立动态对象。分别见上面的a和b.
2.建立动态对象(即给对象分配动态空间时),一般格式为

new <类名> 
new <类名> (<初值列表>)
//new后面的是对象的声明

以下针对于对象

3.访问对象(即访问对象的数据成员和成员函数)时,必须通过对象指针来访问。这个对象指针即是对象空间的起始地址,所以要先定义一个指向本类的指针变量来存放该地址(这个声明和定义类似于类似于C的内容)。

<对象指针名> -> <公有成员>
(*<对象指针名>).<公有成员>

4.虽然对象同时包含了数据和函数两种成员,但他与一般变量有所不同,对象所占据的内存空间只是用于存放数据成员(不包括静态数据成员),成员函数不在每一个对象中存储副本。
当一个类定义了n个对象时,也就是n组同样大小的空间用于存放n个对象中的数据成员,但是,不同的对象都调用同一个函数代码段。而this指针就能够保证不同的对象调用成员函数时能够引用各自的数据成员。
在每一个成员函数(静态成员函数除外)中都含有一个特殊的指针,即是this指针,他的值就是当前被调用成员函数的对象空间所在的地址,也就是该类对象的起始地址。因此,this指针是隐含与每一个成员函数(包括构造函数和析构函数)中的特殊指针,他用于正在被成员函数操作的对象。
如在:

int Box::volume()
{
    return(h*w*l);
    //等于return(this->h*this->w*this->l);
}

添:this指针是一个const指针,成员函数不能对其进行赋值。

再来一粒

/**************************************************************

假设有一个点类point,具有两个实数坐标,希望程序完成以下功能:
1.主程序为point申请10个连续空间.
2.要求调用一个函数Set()从键盘输入10个对象的属性,并顺序存入申请的内存中.
3.要求调用一个函数Display()显示10个对象的值.
4.要求调用一个函数Length()计算这些点连成一条折线时,这条折线的长度.
5.程序借宿时,删除申请的内存.
6.演示析构对象(动态对象或堆对象)的执行顺序.

**************************************************************/

//-----------------------------------point.h
#ifndef _POINT_H_
#define _POINT_H_

#include "iostream"
using namespace std;

class point
{
public:
    point(double =0,double =0);
    double Getx(),Gety();
    void Setxy(double,double);
    ~point();
private:
    double x,y;
};

#endif

//-----------------------------------point.cpp
#include "point.h"

point::point(double a,double b)
{
    x=a;
    y=b;
}

double point::Getx()
{return x;}

double point::Gety()
{return y;}

void point::Setxy(double a,double b)
{
    x=a;
    y=b;
}

point::~point()
{
    cout<<"delete it!"<<"("<<x<<","<<y<<")"<<endl;
}
//-----------------------------------main.cpp

#include "point.h"
const int num=4;

void Set(point *);
void Display(point *);
double Length(point *);

int main()
{
    point *p=new point[num];
    if(p==NULL)
    {
        cout<<"地址申请失败,结束程序运行!\n";
        return 0;
    }
    Set(p);
    cout<<"内存块的数据如下:";
    Display(p);
    cout<<"组成的折线长度为:";
    cout<<Length(p)<<endl;
    delete []p;     //该格式用于释放指针指向的连续的存储空间,比如数组对象指针空间

    system("PAUSE");
    return 0;
}
//给内存块赋值的函数
void Set(point *po)
{
    double a,b;
    for(int i=0;i<num;i++)
    {
        cout<<"Input 第"<<i+1<<"个对象的两个数据成员的值:";
        cin>>a>>b;
        (po+i)->Setxy(a,b);
    }
}
//显示内存块值的函数
void Display(point *po)
{
    for(int i=0;i<num;i++)
    {
        cout<<"("<<(po+i)->Getx()<<","<<(po+i)->Gety()<<")"<<endl;
    }

}
//计算折线长度的函数
double Length(point *po)
{
    double sum=0,a1,b1,a2,b2;
    a1=po->Getx();
    b1=po->Gety();
    for(int i=1;i<num;i++)
    {
        a2=(po+i)->Getx();
        b2=(po+i)->Gety();
        sum=sum+sqrt((a1-a2)*(a1-a2)+(b1-b2)*(b1-b2));
        a1=a2;
        b1=b2;
    }
    return num;
}

———————————–const————————————

五: const常量和宏常量的区别:

(1) 编译器处理方式不同
  define宏是在预处理阶段展开。
  const常量是编译运行阶段使用。
(2) 类型和安全检查不同
  define宏没有类型,不做任何类型检查,仅仅是展开。
  const常量有具体的类型,在编译阶段会执行类型检查。
 

 // 如格式:
 const <数据类型名> <常量名> = <表达式>;
 //如 const float pi=3.1415

 
(3) 存储方式不同
  define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。
  const常量会在内存中分配(可以是堆中也可以是栈中)。

区分下面(对上页的再说明):
1).可以声明指向常量的指针,此时不能通过指针来改变所指向对象的值,但指针本身可以改变,指向其他的对象。

const char *name1="Zhang Hua";  //name1是指向字符串常量的指针
char s[]="Wang lei";
name1=s;                //正确,name1本身的值可以改变,也就是可以指向另外的对象
*name1="Li Ming";       //错误,不能通过name1改变所指的内容

2)也可以声明指针常量,这时指针本身的值不能改变。

char *const name2="Zhang Hua";
name2="Wang Lei";       //错误,name2是指针常量,值不能改变,也就是他所指的对象不能改变。

我们使用const的主要目的是对某些对象中的数据进行一定程度的保护。

在类中的情况如下表所示:

这里写图片描述

下面贴出一则栗子

//------------------------------test1.h

#ifndef _TEST1_H_
#define _TEST1_H_

class Student
{
public:
    void input(int pid,char pname[],float pscore);
    void display();
private:
    int id;
    char name[10];
    float score;
};

#endif

//---------------------------test1.cpp

#include "test1.h"
#include "iostream"
using namespace std;
void Student::input(int pid,char pname[],float pscore)
{
    id=pid;
    strcpy(name,pname);
    score=pscore;
    //构造函数和析构函数的声明和定义分别在h文件和c文件里自己添加
}
void Student::display()
{
    if(score>90)
    cout<<id<<'\t'<<name<<'\t'<<score<<endl;
}

//-------------------------main.c
#include "test1.h"
#include "iostream"
using namespace std;

const int NUM=5;

int main()
{
    Student st[NUM];
    int i,j;
    char na[10];
    float s;

    for(i=0;i<NUM;i++)
    {
        j=i+1;
        cout<<"输入学号、姓名、成绩:"<<j<<' ';
        cin>>na>>s;
        st[i].input(j,na,s);
    }
    cout<<"输出数据"<<endl;
    cout<<"学号"<<"\t姓名"<<"\t成绩"<<endl;
    for(i=0;i<NUM;i++)
    {
        st[i].display();
    }

    system("PAUSE");
    return 0;
}

此时用const 时程序无误.

这里写图片描述

而将

const int NUM=5换成#define NUM 5
-----不管这个预编译是放到main源文件中还是放到test1头文件中,均有下面情况

这里写图片描述

对于这一点,我还是没有理解,希望有高手可以解答,在此谢过了。

上面的栗子也牵涉到对象数组这么个问题,对象数组的元素是对象,通过这个对象,就能访问其公有成员,包括数据成员和成员函数,引用时如上所示。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值