声明,定义,初始化,实例化

简介: 声明,定义,初始化,实例化


相信很多小伙伴这几个词的概念还没有搞得很懂,今天我来举几个小李子帮助大家深刻理解。有用的话点赞再走哦!

引入:为什么定义变量时要声明和定义分离呢

先来了解变量声明和定义的关系

 为了可以把程序拆成多个逻辑部分来编写,通常支持分离式编译的机制,该机制可以允许我们将程序分割为多个文件,每个文件具有各自的作用,可独立被编译。

下边是实现飞机大战时使用分离式编译的写法,每一个文件执行各自的功能,出错时也方便寻找错误。

 如果将程序分为多个文件,就需要有在文件中共享代码的方法,一个文件的代码中可能需要使用另一个文件中的变量。举一个常见的例子就是C++中std::cout和std::cin,他们定义在标准库中,却能被我们写的程序使用。

为了支持分离式编程,C++将声明和定义分开,声明使该名字被程序所知,一个文件想使用别处定义的名字就必须要包含对哪个名字的声明,定义则是负责创建与名字关联的实体。

也就是声明后,不一定有实体,而定义就是创建实体。

 变量声明规定了变量的类型和名字,定义也规定了变量的类型和名字,但是除此之外,定义还会申请空间,也可能为该变量赋一个初始值。

如果想声明一个变量而不是定义它,就在变量名前加上extern,而不是显式地初始化变量

extern int i; //声明i而不是定义i

int j; //声明并且定义

 但任何包含了显示初始化的声明即成为定义,我们给由extern关键字标记的变量赋上初始值,这么做就抵消了extern的作用。extern语句如果包含初始值就不再是声明而是定义了,因为我们给该变量创建实体以保存其初始化的数值。

说了很多,不如实践演示一波

这里的报错就是未声明标识符。是编译错误。

当我们给extern修饰的变量附上初始值,就会发现可以正常运行。

声明就像是给你一个承诺,但是我可能会忘记实现承诺,从而导致错误。

 你哥们要买房,过来告诉你借点钱,你刚好兜里有点,爽快的答应了,说过一会儿转到他的账上,但是一转眼你忘记了这件事,你哥们首付都交了,又打电话过来问你钱转了吗?怎么没收到,你忽然才想起来,然而你的小积蓄给女朋友买了一个大戒指,已经没有钱了,你和兄弟说完兄弟就崩溃了,答应是全款,这下没钱付,要付违约金,你哥们就崩溃了。这就是因为你定义了,说马上把钱打过去,然而你没打,哥们有钱吗?没有,哥们崩溃了。


声明可以多次声明,你当然可以给多个哥们画大饼,不同的程序都可以得到来自你的声明,他们都觉得事情已经妥了,然而声明过来的变量却没有定义。许多程序(哥们)就崩溃了。

声明可以多次声明,但是定义只能有一次。变量的定义只能出现在一个文件中。

 总结一下就是声明和定义分离,可以使其他想用到该文件中某变量的文件通过声明使用该变量。

函数的声明和定义

我们可以类比变量的声明和定义,其实都一样的。

 还记得在C语言中我们写main函数外的函数都要放在main函数下边,不然就要在前边写一个函数声明吗?(先看现象,后挖掘本质)

举一个很常见的例子

此时程序正常运行

 此时就会报错,找不到Add函数,这是因为程序运行时是从上到下一次执行的,在main函数前边没有发现Add函数,所以会报错,我们要声明一下,告诉编译器我们写了Add函数了的。

 对于第一次运行是可以运行的原因就是,第一次运行时同时进行了声明和定义。

 对于函数,同样可以用extern修饰,但是extern可以省略。

在这里,声明和定义的关系我想你已经烂熟于心了。

类的声明和定义

这里只谈类的声明和定义,深入了解一下?类和对象

类的声明和定义不同于前边。

 我们可以仅仅声明一个类暂时不定义他,这种声明称为前向声明,他在声明之后定义之前是一个不完全类型。

 如果看了前边我所推荐的文章就可以更加理解,对于不完全类型,使用场景十分有限,由于他没有实体,编译器无法知道存储该数据成员需要多少空间,所以类必须先被定义,然后才能引用或使用指针访问其成员。

 类的定义必须要有类名和类体,类体中的变量称为类的属性和成员变量,类中的函数称为类的方法或者成员函数。

类的两种定义方式:

  1. 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内
    联函数处理。
class Person
{
public:
  void Print()
  {
    cout << "hello" << endl;
  }
  int _age;
  int _grade;
};
  1. 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::

初始化的概念

 初始化在计算机编程领域中指为数据对象或变量赋初值的做法,初始化和声明是有明显区别的,变量声明一定是先于初始化进行的,一个包含初始化的声明则通常被称为定义。

 C++定义变量时如果没有给其赋初始值,会根据其位置判断要不要给他默认初始值。默认初始值由该变量的类型来确定。

 如果在任意函数外定义的变量赋值为0,定义在函数内部的内置类型不被初始化,一个没有被初始化的内置类型的值是未定义的,如果试图拷贝或者以其他形式访问该类值将会引发错误。

如图

如果将下边的放开

 在C++中,初始化用=号的方式,很容易让人们认为初始化是赋值的一种,然而初始化和赋值完全是两种不同的操作,人们很容易把二者的区别混为一谈。

 初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象非当前的值擦除,用一个新的值来代替。

一个变量只会初始化一次,再次就是赋值,不然就会重定义。

如果再次初始化就会报错

实例化的概念

 实例化是指在面向对象编程中,用类创建对象的过程,是将一个抽象的概念类,具体到该类实物的过程。

 定义一个类,但是并没有有分配实际的内存空间来存储它。一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量。

 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。

总结一下:

 实例化是面向对象过程中用类创建出对象的过程,初始化是为创建出的数据对象赋上初值的过程,声明变量或函数时可以理解为一个承诺,告诉编译器有我这个变量或者函数存在,但是真的存在吗?他不一定已经定义过了,在编译时我知道他是存在的,链接时找遍全场都没有找到,程序就崩溃了。声明是告诉你我存在,定义是生成实体。

 本文到这里就结束啦,有用的话留一个赞再走叭,如果你的慧眼金睛发现了问题,一定要说哦,我会虚心改正哒。

目录
相关文章
|
5月前
|
C++
C++程序中的类声明与对象定义
C++程序中的类声明与对象定义
56 1
|
5月前
|
存储 程序员 编译器
C++11:声明 & 初始化
C++11:声明 & 初始化
36 0
|
5月前
|
C++
26类的声明和对象的定义
26类的声明和对象的定义
33 0
C#中声明、初始化和实例化
C#中声明、初始化和实例化
|
5月前
|
C语言
C11中类成员变量定义时初始化问题
C11中类成员变量定义时初始化问题
66 0
|
编译器 数据库 C语言
8.3 C++ 定义并使用类
C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存等底层资源,对于初学者来说可能会有一定的难度。
定义了一个类A,S是类外的一个函数,通过A.S=S进行赋值
假设类 A 已经定义好了,现在可以通过 A.S = S 的方式将函数 S 赋值给类 A。这样做的效果是,将 S 函数作为类 A 的一个属性,并且可以通过该属性来调用函数 S。 下面是一个简单的例子:
|
C#
类的定义
类的定义
124 0
|
Kotlin
【Kotlin】Kotlin 构造函数 ( 主构造函数 | 主构造函数声明属性 | init 初始化代码块 | 次构造函数 | 构造函数委托 | 调用构造函数创建实例对象 )(二)
【Kotlin】Kotlin 构造函数 ( 主构造函数 | 主构造函数声明属性 | init 初始化代码块 | 次构造函数 | 构造函数委托 | 调用构造函数创建实例对象 )(二)
162 0
|
Kotlin
【Kotlin】Kotlin 构造函数 ( 主构造函数 | 主构造函数声明属性 | init 初始化代码块 | 次构造函数 | 构造函数委托 | 调用构造函数创建实例对象 )(一)
【Kotlin】Kotlin 构造函数 ( 主构造函数 | 主构造函数声明属性 | init 初始化代码块 | 次构造函数 | 构造函数委托 | 调用构造函数创建实例对象 )(一)
276 0