c++类对象的初始化笔记(1)

本文探讨了C++中类成员变量如果是内置类型或复合类型时,默认构造函数无法确保其初始化为确定值的问题。通过示例展示了即使使用=default构造函数,值仍然是不确定的。解决方案是在定义成员变量时直接给予确定的初始值。文章还提到了=default构造函数的内外部声明,并提供了相关的参考资料。
摘要由CSDN通过智能技术生成

目录

1. 类成员变量是内置变量或者复合类型

2. 内置类型,即基本类型

3. 复合类型

4. 合成的默认构造函数为内置类型的成员变量初始化的值不确定

5. =default形式的默认构造函数,也不能初始化为内置类型的成员变量初始化一个确定的值

6. =default出现在类外部

7. 解决不确定初始化值的问题

8. 参考资料


1. 类成员变量是内置变量或者复合类型

      《C++ primer》第五版中有讲:

有一条准则,即定义在块中的内置类型或复合类型(数组和指针)默认初始化后,对象的值是不确定的。这条准则同样也适用于默认构造函数,因此,成员变量是内置类型或者复合类型,这个时候,就需要自定义一个默认构造函数,否则,在创建类的对象后就会出现成员变量初始值未被定义的情况。

      这一条准则,很耐人寻味,很多情况下,我们定义的类的成员变量很容易是内置变量或者复合类型。所以我们需要分清楚哪些类型是内置变量,哪些是复合变量。这对于这条准则的运用很重要。

2. 内置类型,即基本类型

类型含义最小尺寸(bit)
bool布尔类型-
char字符8
wchar_t宽字符16
char16_tUnicode字符16
char32_tUnicode字符32
short短整型16
int整型16
long长整型32
long long长整型64
float单精度浮点型6位有效数字
double双精度浮点型10位有效数字
long double扩展精度浮点型10位有效数字

3. 复合类型

常见的有

  1. 指针

  2. 引用

为了便于理解,我们还是利用案例来说明情况

4. 合成的默认构造函数为内置类型的成员变量初始化的值不确定

//sales_data.h
#ifndef SALES_DATA_H
#define SALES_DATA_H

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

class SalesData
{
 public:
   void GetSaleBn()
   {
         cout << "sales_isbn:" << sale_isbn << endl;
   }

 private:
   int sale_isbn;

};

#endif
//main.cpp
#include "sales_data.h"
#include <iostream>

int main()
{
    std::cout << "SalesData totoal before..." << std::endl;
    SalesData total;
    total.GetSaleBn();
    std::cout << "SalesData totoal after..." << std::endl;

    return 0;
}

编译方法使用以下Makefile:

TGT:= main
SRC:= $(wildcard *.cpp)
OBJ:= $(patsubst %cpp,%o,$(SRC))

CPPFLAGS := -I. 

all:$(TGT)
>---@echo "Make successful [0]"

$(TGT):$(OBJ)
>---g++  $^  -o  $@

%.o:%.cpp
>---g++ $(CPPFLAGS) $<  -c


clear:
>---rm $(OBJ) $(TGT) log.log
.PHONY: all clear

运行结果如下:

goodstudy@xgoodstudyVPCEG27YC sales_data (study) $ ./main 
SalesData totoal before...
sales_isbn:32764(值1)
SalesData totoal after...
xugoodstudyuegoodstudyCEG27YC sales_data (study) $ ./main 
SalesData totoal before...
sales_isbn:32766(值2)
SalesData totoal after...
//如果不初始化,对象的内置变量成员值是不确定的,这样的程序是不健壮的,值得我们警惕。

5. =default形式的默认构造函数,也不能初始化为内置类型的成员变量初始化一个确定的值

sales_data.h文件内容如下

#ifndef SALES_DATA_H
#define SALES_DATA_H

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

class SalesData
{
 public:
    SalesData() = default;
    SalesData(int sale_a):sale_isbn(sale_a)
    {
    }
    void GetSaleBn()
    {
          cout << "sales_isbn:" << sale_isbn << endl;
    }

 private:
   int sale_isbn;
};

#endif

编译命令参考以上,编译后,编译生成目标文件 ./main

xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main 
SalesData totoal before...
sales_isbn:32767(值1)
SalesData totoal after...
xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main 
SalesData totoal before...
sales_isbn:32764(值2)
SalesData totoal after...
xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main 
SalesData totoal before...
sales_isbn:32766(值3)
SalesData totoal after...
xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ 

运行结果显示,手动构造函数和合成的构造函数效果都一样,都不能初始化一个确定的值。

《C++ primer》第五版讲到,=default既可以声明在类的内部,也可以作为定义出现在类的外部。如果出现在类的内部,表明默认构造函数是内联的,如果出现在类的外部,则表明此构造函数不是内联的。接下来我们补充一个=default出现在类外部的案例

6. =default出现在类外部

#ifndef SALES_DATA_H
#define SALES_DATA_H

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

class SalesData
{
 public:
   //  SalesData() = default;
    SalesData();
    SalesData(int sale_a):sale_isbn(sale_a)
    {
    }
    void GetSaleBn()
    {
          cout << "sales_isbn:" << sale_isbn << endl;
    }

 private:
   int sale_isbn;

};

#endif
//sales_data.cpp
#include"sales_data.h" 
SalesData::SalesData() =default;

编译参考以上,结果如下

xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main 
SalesData totoal before...
sales_isbn:32767(值1)
SalesData totoal after...
xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main 
SalesData totoal before...
sales_isbn:32764(值2)
SalesData totoal after...
xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main 
SalesData totoal before...
sales_isbn:32767(值3)
SalesData totoal after...

结论文章开头说的一样。

如果想让上述案例成员变量的值是确定的,可以有多种方法,其中一种就是可以在定义内置成员变量时,就显式的给出确定的值,以下说明了这点。

7. 解决不确定初始化值的问题

//sales_data.h
#ifndef SALES_DATA_H
#define SALES_DATA_H

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

class SalesData
{
 public:
    SalesData() = default;
    SalesData(int sale_a):sale_isbn(sale_a)
    {
    }
    void GetSaleBn()
    {
          cout << "sales_isbn:" << sale_isbn << endl;
    }

 private:
   int sale_isbn = 0;

};

#endif

main.cpp参考之前的案例,结果如下

xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main
SalesData totoal before...
sales_isbn:0
SalesData totoal after...

8. 参考资料

《C++ primer》第五版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青草地溪水旁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值