C++自学笔记18(成员初始化列表和初始化对象)

成员列表初始化

创建变量,并将其初始化是创建函数的必要部分。

#include <iostream>
#include <string>
class Entity 
{
private:
    std::string m_name;

public:
    Entity()
    {
        m_name = "nothing"
    }
    Entity (const std::string& name)
    {
        m_name = name;
    }
    const std::string& GetName()const
    {
        return m_name;
    }
};
int main()
{
    Entity e;
    std::cout<<e.GetName()<<std::endl;

    Entity e1("shaojie");
    std::cout<<e1.GetName()<<std::endl;

    std::cin.get();
}

控制台显示

nothing

shaojie

在这里我们用到了两个构造函数,并且对函数进行重载。目的就是在不输入时初始化m_name为nothing,在有输入时初始化其为shaojie。

我们用成员初始化列表再写一遍函数

#include <iostream>
#include <string>
class Entity 
{
private:
    std::string m_name;

public:
    Entity():m_name("nothing")
    { 
    }
    Entity (const std::string& name):m_name(name)
    {
    }

    const std::string& GetName()const
    {
        return m_name;
    }
};
int main()
{
    Entity e;
    std::cout<<e.GetName()<<std::endl;

    Entity e1("shaojie");
    std::cout<<e1.GetName()<<std::endl;

    std::cin.get();
}

控制台显示

nothing

shaojie

我们就是将花括号内部赋值换到:后边,对就是这么简单。它有什么作用呢?看下面的代码

#include <iostream>
#include <string>
class Entity 
{
private:
    std::string m_name;
    int x,y,z;
public:
    Entity():m_name("nothing")
    { 
        x = 0;
        y = 0;
        z = 0;

        void Init();
    }
    Entity (const std::string& name):m_name(name)
    {
    }

    const std::string& GetName()const
    {
        return m_name;
    }
};
int main()
{
    Entity e;
    std::cout<<e.GetName()<<std::endl;

    Entity e1("shaojie");
    std::cout<<e1.GetName()<<std::endl;

    std::cin.get();
}

 我们加入xyz并将其初始化,还加入函数Init()。看上去乱乱的,我们将其如下改写

#include <iostream>
#include <string>
class Entity 
{
private:
    std::string m_name;
    int x,y,z;
public:
    Entity():m_name("nothing"),x(0),y(0),z(0)
    { 
        void Init();
    }
    Entity (const std::string& name):m_name(name)
    {
    }

    const std::string& GetName()const
    {
        return m_name;
    }
};
int main()
{
    Entity e;
    std::cout<<e.GetName()<<std::endl;

    Entity e1("shaojie");
    std::cout<<e1.GetName()<<std::endl;

    std::cin.get();
}

 我们将数值初始化放在:后边,这样只要看花括号内就是到时执行某种函数。

private:
    std::string m_name;
    int m_score;
public:
    Entity():m_name("nothing"),score(0)
    {
       
    }

 还有一件事我们在初始化多个时“:”后要按照private创建变量的顺序去初始化,否则部分编译器会报错。

初始化成员列表就是将变量初始化与函数分开,变量放在:后,函数放在{},加强代码可读性。

 初始化对象

栈建立

初始化对象我们无形中用过许多次了自从如何创建Log类

#include <iostream>
#include <string>
class Entity 
{
private:
    std::string m_name;

public:
    Entity():m_name("nothing"){}
    Entity (const std::string& name):m_name(name){}

    const std::string& GetName()const
    {
        return m_name;
    }
};
int main()
{
    Entity e;
    std::cout<<e.GetName()<<std::endl;

    Entity e1("shaojie");
    std::cout<<e1.GetName()<<std::endl;

    std::cin.get();
}

我们用上文提到的Entity类举例子,初始化对象实际就是创建实例在main中。

e和e1两个对象分别在Entity中用两个不同的初始化函数,这就是初始化还对象。

不过还有一个问题Entity e ;与Entity e1("shaojie");都是在栈(笔记15提到过)上创建的,就是说我们如果在函数内创建对象,函数结束,栈内内存都被释放,如下栗子。

#include <iostream>
#include <string>
class Entity 
{
private:
    std::string m_name;

public:
    Entity():m_name("nothing"){}
    Entity (const std::string& name):m_name(name){}

    const std::string& GetName()const
    {
        return m_name;
    }
};

void Function()
{
    Entity e1("shaojie");
}

int main()
{

    std::cout<<e1.GetName()<<std::endl;

    std::cin.get();
}

 我们将Entity e1的初始化放在Function内,因为我们写的创建的对象是在栈中建立的,所以运行到Entity的}时,e1就被释放,无法打印出“shaojie”。

堆建立

怎么办呢?在堆上建立。

#include <iostream>
#include <string>
class Entity 
{
private:
    std::string m_name;

public:
    Entity():m_name("nothing"){}
    Entity (const std::string& name):m_name(name){}

    const std::string& GetName()const
    {
        return m_name;
    }
};
int main()
{
    //Entity e1("shaojie");
    Entity* e1 = new Entity("shaojie");
    std::cout<<(*e1).GetName()<<std::endl;
    delete e1;
    std::cin.get();
}

来看看我们更改了什么 

1.Entity e1("shaojie");我们对Entity更改为指针

2.我们在Entity ("shaojie")这个构造函数之前加入了new

3.输出流改为*e1指针

4.加入了delete e1

我先来解释3,就是因为1Entity变为指针所以他要变成指针。那么为什么1要变为指针呢?

因为2的关键字“new”。new就是在堆上创建对象的关键字,他将对Entity(“shaojie”)进行操作并返回Entity在堆上分配的地址,正因为其返回的是一个地址所以解释了2进而解释了1.

4因为new的存在我们在堆上创建了对象,还记得堆与栈的区别,我们需要选择位置手动释放e1

delete e1;的位置看我们的意愿。

总的来说,就在栈与堆的生存时间上,那我们会不会在堆建立时候忘记delete这行代码呢?可能是会的。智能指针可以帮助我们(挖坑)

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值