首页 > 编程语言 >C++自学笔记18(成员初始化列表和初始化对象)

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

时间:2024-07-26 12:24:49浏览次数:10  
标签:std 初始化 const name 18 C++ Entity string

成员列表初始化

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

#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这行代码呢?可能是会的。智能指针可以帮助我们(挖坑)

标签:std,初始化,const,name,18,C++,Entity,string
From: https://blog.csdn.net/weixin_64418869/article/details/140684374

相关文章

  • C++ primer plus 第16章string 类和标准模板库, 函数符概念
    C++primerplus第16章string类和标准模板库,函数符概念C++primerplus第16章string类和标准模板库,函数符概念文章目录C++primerplus第16章string类和标准模板库,函数符概念16.5.1函数符概念程序清单16.15functor.cpp16.5.1函数符概念正如STL定......
  • C++ primer plus 第16章string 类和标准模板库, 函数对象
    C++primerplus第16章string类和标准模板库,函数对象C++primerplus第16章string类和标准模板库,函数对象文章目录C++primerplus第16章string类和标准模板库,函数对象16.5函数对象16.5函数对象很多STL算法都使用函数对象–也叫函数符(fiunctor)。......
  • React18学习笔记 第六篇:对React内部运作深入了解
    Part1组件之间的概念差异·组件组件是我们为了描述用户界面的一部分而编写的,它只是一个普通的JavaScript函数,但它是一个返回React式元素的函数,这些元素是用JSX语法来编写的,我们可以把组件理解为一个“蓝图”或“模板”。·组件实例一个组件实例就像是一个组件的实际物理表......
  • 当你第一次用C++string的assign会遇到这种情况
    当你第一次用string的assign时,会发现有一点小区别,见以下代码:stringstr1;str1.assign("helloC++");cout<<str1<<endl;stringstr2;str2.assign(str1,5);cout<<str1<<endl;stringstr3;str3.assign("helloC++",5);cout<<......
  • 使用pybind11封装c++的dll,供python调用
    用pip安装好pybind11 文件清单,都写在一个目录里//文件名:add.cppextern"C"doubleadd(doublein1,doublein2){returnin1+in2;}//文件名:sub.cppextern"C"doublesub(doublein1,doublein2){returnin1-in2;}//文件名:mul.cppextern"......
  • P9304 「DTOI-5」3-1题解,c++树的遍历例题
    题意给定以n(1≤n≤1......
  • C/C++默认生成的几个函数s
    一、关键词类/结构体默认生成。拷贝/移动+构造/赋值=组合不同方式有4种,除默认、析构,共计6种。在使用时:拷贝/移动+赋值的,都是定义和赋值分开;拷贝/移动+构造的,都是定义和赋值一起。二:知识点默认构造函数Student():age(0){};拷贝构造函数Student(constStudent&i......
  • C++ typeid 关键字的注意事项
    typeid 是C++的一个关键字,用于动态类型获取。typeid 运算符与RTTI(运行时类型信息)密切相关,它返回一个指向 std::type_info 对象的引用,该对象表示了表达式的类型。使用 typeid 时,需要注意以下几个方面:需要#include <typeinfo>头文件:要使用 typeid,应在代码中包含 <t......
  • C++ 虚基类注意事项
    C++中的虚基类(VirtualBaseClass)是一个重要的概念,主要用于解决多重继承中的菱形继承问题,即当一个派生类通过多条路径继承同一个基类时,基类在派生类中会有多个副本,导致资源浪费和不必要的复杂性。以下是C++虚基类的一些详细注意事项:1.虚基类的定义与声明定义方式:虚基类并不......
  • C++中的智能指针与裸指针有什么区别?
    在C++中,智能指针是一种特殊类型的指针对象,它能自动管理内存的分配和释放。智能指针与裸指针(即传统的指针)之间有以下区别:自动资源管理:智能指针通过使用引用计数或其他机制来自动管理内存资源的分配和释放。这意味着当不再需要指针指向的对象时,智能指针会自动释放内存,避免......