首页 > 编程语言 >C++ 关于构造函数和this调用的思考

C++ 关于构造函数和this调用的思考

时间:2022-09-07 21:55:12浏览次数:93  
标签:初始化 调用 int 成员 C++ 构造函数 CLS

文中一系列思考和内容引发自以下问题:
我需要在一个类的构造函数中调用另一个对象的构造函数,并使用this初始化其中的一个引用成员。

主要遇到的问题:

1. 构造函数的初始化列表中能访问this吗?

很明显c++创建一个对象分为两部分,创建内存和调用构造函数。
显然在初始化列表中,当前对象占用的内存已经创建好了,ok,this是可以访问的,只是其中的某些成员是没有初始化的(因为没有构造函数还没执行完,只能说对象是部分有效的)。

那也间接说明一个问题,在构造函数的函数体中使用this是完全可靠的,所有编译器可以自动初始化的成员都完成了初始化(比如基类的成员、带有默认构造函数的成员,注意具体初始化顺序是由类成员定义顺序确定的),但当前类的部分未在初始化列表中初始化的且没有默认构造函数类成员变量(比如常见的c++内置类型,int、float、指针等)的值是未定义的。

2. 构造函数参数与成员同名

构造函数的形式如下:带有一个和类成员同名的参数。打印输出只是为了验证成员变量是否初始化。

复制代码
class A
{
public:
    A(int a): a(a){cout<<a<<endl;}
private:
    int a;
};
复制代码

由于初始化列表中不能直接出现this,所以编译器会处理这种重名的情况。也就说,你不能在构造函数的初始化列表中显式用this做限定符,比如下面代码是无法通过编译的:

A:this->a(a){}

3. 如何在一个类的构造函数汇中调用另一个构造函数

构造函数是不允许嵌套调用的,但可以调用不同的重载形式。比如下面代码:(注意这是一道面试题目)

复制代码
struct CLS
{
    int m_i;
    CLS( int i ) : m_i(i){}
    CLS(){CLS(0);}
};
int main()
{
    CLS obj;
    cout << obj.m_i << endl;
    return 0;
}
复制代码

输出是多少?

---------------------------------------------------------------------------

答案是未知,因为m_i是未初始化的变量,是个野值。

"CLS(0);"的语句表示创建一个临时的CLS对象,并把该对象的成员m_i初始化为0。当前对象的值并没有初始化。

 

如果需要实现构造函数类调用另一个构造函数,需要借助于placement new运算符。代码如下:

复制代码
struct CLS
{
    int m_i;
    CLS( int i ) : m_i(i){}
    CLS()
    {
        new (this)CLS(0);
    }
};    
复制代码

如果你对placement new不了解,建议看看c++ primer或者TCPL。

 

在c++11中可以直接通过委托或继承构造函数的形式实现上面功能。

struct CLS
{
    int m_i;
    CLS( int i ) : m_i(i){}
    CLS():CLS(0){}
};

 

4. 解决方案

写到这里。我对于构造函数的初始化列表中引用this的情况基本了解,可以用下面代码解决本文开始提出的问题。

复制代码
class Context;
class Ref
{
public:
    Ref(Context&context):context(context){}
private:
    Context &context;
};
class Context
{
public:
    Context():ref(*this){}
private:
    Ref ref;
};
复制代码

复述下开始的问题:我需要在一个类的构造函数中调用另一个对象的构造函数,并使用this初始化其中的一个引用成员。

类Context会在其构造函数的初始化列表中通过this调用Ref的构造函数。

 

5. 参考资料

[1] 从一道题谈C++中构造函数调用构造函数    http://www.cnblogs.com/chio/archive/2007/10/20/931043.html

[2] c++ 一个构造函数 调用 另一个 构造函数    http://www.cnblogs.com/ayanmw/archive/2012/08/20/2647808.html

标签:初始化,调用,int,成员,C++,构造函数,CLS
From: https://www.cnblogs.com/zhoug2020/p/16667412.html

相关文章

  • AC C++ 1.6函数
    1、C++中,int返回值的函数可以写return,不会报错,但是返回值会是一个随机值2、函数定义与函数声明,声明不需要写函数体,形参名也可以没,只有一个形参类型就行。声明和定义前后顺......
  • C++中构造函数的超详细讲解
    转:https://blog.csdn.net/guishangppy/article/details/125876729C++在C语言的基础上增加了类和对象的概念,官方对类和对象的解释是:对象是类的实例化,类是对象的抽象,其实这......
  • 使用c++ librados库操作ceph pool
    centos需要安装依赖:yuminstalllibrados2代码如下://代码中使用到的部分参数://cluster_name(默认为ceph)//user_name(默认为client.admin)//con......
  • C++ 由快排学习到的的随机数等知识
    起:力扣的912题数组排序,想着先用快速排序来写写,在实际用c++编写的时候,有一些之前没注意到的细节问题造成了一些麻烦。912.排序数组-力扣(LeetCode)   快排......
  • 详解Shell脚本中调用另一个Shell脚本的三种方式
    主要以下有几种方式: CommandExplanationfork新开一个子Shell执行,子Shell可以从父Shell继承环境变量,但是子Shell中的环境变量不会带回给父Shell。exe......
  • shell调用问题
    提示:以下是介绍为什么写这篇文章:如何再shell脚本中调用其他脚本?顺序调用会保证脚本的顺序执行吗?一、在Shell脚本中调用另一个Shell脚本的三种方式先来说一下......
  • python调用其他.py文件
    一、python程序本质python是一个解释性的动态编程语言,所以它不需要像编译型的语言一样在程序编写完成之后还要通过编译才可以去使用。python编写的所有程序都是一个以py后......
  • 延宕执行,妙用无穷,Go lang1.18入门精炼教程,由白丁入鸿儒,Golang中defer关键字延迟调
    先行定义,延后执行。不得不佩服Golang设计者天才的设计,事实上,defer关键字就相当于Python中的try{...}except{...}finally{...}结构设计中的finally语法块,函数结束时强制......
  • ACM模式各种输入总结 C++
    一、整型数组输入:(很简单)在终端的一行中输入固定数目的整型数字,并存到数组中,中间以空格分隔。示例:3123intn;cin>>n;vector<int>nums(n);......
  • vscode环境配置(C/C++)
    一.MinGW和vscode的简单了解1.MinGW是什么?MinGW(MinimalistGNUonWindows)。它实际上是将经典的开源C语言编译器GCC移植到了Windows下,并且包含了Win32API,因此可......