我的编程空间,编程开发者的网络收藏夹
学习永远不晚

一文带你分清C++的定义,声明和初始化

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

一文带你分清C++的定义,声明和初始化

定义

变量的定义用于为变量分配存储空间,还可以为变量指定初始值。

int units_sold;
double sales_price, avg_price;
std::string title;
Sales_item curr_book; // class Sales_item

初始化

C++ 支持两种初始化变量的形式:复制初始化和直接初始化。复制初始化语法用等号(=),直接初始化则是把初始化式放在括号中。

int ival(1024); // direct-initialization
int ival = 1024; // copy-initialization

初始化不是赋值。初始化指创建变量并给它赋初始值,而赋值则是擦除对象的当前值并用新值代替。

当定义没有初始化式的变量时,系统有时候会帮我们初始化变量。

1.内置类型变量

(Built-in Types,即int,float,double,void,char,bool等。注意string是标准库定义的类型,不是内置类型)

在函数体外定义的变量都初始化成 0,在函数体里定义的内置类型变量不进行自动初始化。

2.类

类通过定义一个或多个构造函数来控制类对象的初始化。创建类类型的新对象,都要执行构造函数,保证每个对象的数据成员具有合适的初始值。

构造函数可以包含一个构造函数初始化列表,以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个数据成员后面跟一个放在圆括号中的初始化式。与任意的成员函数一样,构造函数可以定义在类的内部或外部。

构造函数初始化只在构造函数的定义中而不是声明中指定。

//将 isbn 成员初始化为 book 形参的值,将 units_sold 和 revenue 初始化为 0。
Sales_item::Sales_item(const string &book):
          isbn(book), units_sold(0), revenue(0.0) { }

如果没有提供初始化式,那么就会使用默认构造函数。如果类具有默认构造函数,那么就可以在定义该类的变量时不用显式地初始化变量。例如,string 类定义了默认构造函数来初始化 string 变量为空字符串。

string a;
cout << "a: " << a <<endl;

输出:

a: 

此外,省略初始化列表在构造函数的函数体内对数据成员赋值是合法的。

Sales_item::Sales_item(const string &book)
     {
         isbn = book;
         units_sold = 0;
         revenue = 0.0;
     }

不管成员是否在构造函数初始化列表中显式初始化,类类型的数据成员总是在初始化阶段初始化。初始化发生在计算阶段开始之前。(也就是函数体执行以前)→ 这里似乎有些难以理解,通过后文的实例也许你能明白

在构造函数初始化列表中没有显式提及的每个成员,使用与初始化变量相同的规则来进行初始化。运行该类型的默认构造函数,来初始化类类型的数据成员。内置或复合类型的成员的初始值依赖于对象的作用域:在局部作用域中这些成员不被初始化,而在全局作用域中它们被初始化为 0。

未初始化的变量

局部作用域的内置类型变量将不被自动初始化,这可能导致其成为未初始化的变量。这是常见的程序错误,但编译器无法检测出所有未初始化变量的使用。→ 你肯定可以理解这可能导致的灾难性后果了(这竟然不可以运行,为什么呢?这竟然可以运行,为什么呢?.jpg)再稍微解释一下原因:问题出在未初始化的变量事实上都有一个值。编译器把该变量放到内存中的某个位置,而把这个位置的无论哪种位模式都当成是变量初始的状态。当被解释成整型值时,任何位模式都是合法的值——虽然这个值不可能是程序员想要的。因为这个值合法,所以使用它也不可能会导致程序崩溃。可能的结果是导致程序错误执行和/或错误计算。

声明

声明用于向程序表明变量的类型和名字。定义也是声明:当定义变量时我们声明了它的类型和名字。

可以通过使用extern关键字声明变量名而不定义它。extern 声明不是定义,也不分配存储空间。事实上,它只是说明变量定义在程序的其他地方。程序中变量可以声明多次,但只能定义一次。

extern int i; // declares but does not define i
int i; // declares and defines i

只有当声明也是定义时,声明才可以有初始化式,因为只有定义才分配存储空间。初始化式必须要有存储空间来进行初始化。如果声明有初始化式,那么它可被当作是定义,即使声明标记为 extern:

extern int i = 10; //defines i

在 C++ 语言中,变量必须且仅能定义一次,而且在使用变量之前必须定义或声明变量。

实例

#include <iostream>
#include <string>
using namespace std;

//类x的声明
//如果这一部分放在main()函数后面,报错:error: 'x' was not declared in this scope
//在实际工程中,这部分声明将放在头文件(.h)中,而构造函数及成员函数的定义则放在.cpp文件中
class x{
public:
    x(int a, int b, string c);
    void print_data();
private:
    //类数据成员的变量名最好在开头加一个字母m(即member)
    int ma; 
    int mb;
    string mc;

};

int main(){
    int a1(2); //直接初始化
    int b1 = 3; //复制初始化
    string c1; //默认构造函数初始化string变量为空字符串
    c1 = "dwkw"; //赋值
    x data(a1, b1, c1); //调用构造函数初始化
    return 0;
    print_data();
}

//构造函数定义
x::x(int a, int b, string c):ma(a), mb(b), mc(c){}
//成员函数定义
void x::print_data(){
    cout << "ma: " << ma << endl;
    cout << "mb: " << mb << endl;
    cout << "mc: " << mc << endl;
}

输出:

ma: 2
mb: 3
mc: dwkw

声明时提供初值

如果在类的声明中就对数据成员提供初值,而不在初始化列表中提供,程序可以执行,输出ma的值为1。

class x{
public:
    x(int a, int b, string c);
    void print_data();
private:
    int ma = 1; //声明时提供初值
    int mb;
    string mc;
};
//去掉初始化列表
x::x(int a, int b, string c):mb(b), mc(c){}

这一做法在早期版本不予支持,但从c++11就可以了。[2]

不过这破坏了类的抽象性,并不建议这样做。

查看c++版本的方法:[3]

cout << __cplusplus << endl; //输出c++版本

在构造函数内赋初值,而不用列表

前面提到省略初始化列表在构造函数的函数体内对数据成员赋值是合法的。

//去掉初始化列表,在构造函数体内赋值
//其它代码保持不变
x::x(int a, int b, string c){
    cout << "赋值前: " << endl;
    print_data();
    cout << "赋值后: " << endl;
    ma = 4;
    mb = 5;
    mc = "ser";
}

输出:

赋值前: 
ma: 4199744
mb: 0
mc: 
赋值后: 
ma: 4
mb: 5
mc: ser

实际上我就没写初始化列表,但系统它就会在这里执行初始化。总之就会在执行构造函数体内的语句之前初始化(如果它可以自动初始化),即使根本没写初始化列表。→ 啧,我就像在说绕口令,希望你能明白我的意思

但是ma和mb都是局部作用域(我不确定类作用域是否是局部作用域,但从输出来看,ma不是0,所以应该没有能够初始化)的内置类型变量,不进行自动初始化;mc有默认构造函数,自动初始化为空字符串。

而后,执行构造函数体内部的语句,将对ma和mb进行初始化(我想这里应该是初始化而不是赋值),对mc赋值。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!  

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

一文带你分清C++的定义,声明和初始化

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C++的定义,声明和初始化实例分析

这篇文章主要介绍了C++的定义,声明和初始化实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++的定义,声明和初始化实例分析文章都会有所收获,下面我们一起来看看吧。定义变量的定义用于为变量分配存储空间,
2023-06-29

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录