前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++构造函数互调纠正

C++构造函数互调纠正

作者头像
公众号guangcity
发布2019-11-05 15:41:32
6320
发布2019-11-05 15:41:32
举报
文章被收录于专栏:光城(guangcity)光城(guangcity)

0.导语

现在有这么一个问题,有一个带参数的构造函数,当默认构造去调这个带参数的构造,在Java中大家都明白,直接穿个this(xxx)就可以了,那就在C++中模仿一下,写出下面代码:

代码语言:javascript
复制
class A {
private:
    string name;
    int age;
public:
    A(string name, int age) {
        this->name = name;
        this->age = age;
    }

    A() {
        A("bob", 20);
    }

    void print() {
        cout << name << " " << age << endl;
    }
    // ...
    // ...
};

当调用如下:

代码语言:javascript
复制
A a;
a.print();

输出:

代码语言:javascript
复制
 125156784

一堆垃圾值。。。

发生了意向不到的后果。所以本文来深入分析这个原理。

1.构造互调两方案

这段代码输出的是一个不确定的值,name与age的值并不是我们期待的,原因在于执行A("bob", 20)时,并不是用这一构造函数来初始化当前的内存区,而是初始化了一个临时对象的内存区

具体阐述:A a;这里已经为a分配了内存,然后调用默认构造函数,但是默认构造函数还未执行完,却调用了另一个构造函数,这样相当于产生了一个匿名的临时A对象,它调用A("bob", 20)构造函数,将这个匿名临时对象自己的数据成员name与age初始化后,当执行完这一行,这个匿名临时对象已经被释放掉了,此时a的数据成员并没有得到初始化。于是a的name与age是未初始化的,因此其值也是不确定的。

那么如何在C++中实现构造函数调用构造函数呢?

两种方案,第一种:封装到公共操作到私有函数中;第二种:定点new;

1.1 封装方案

我们将原来的代码改写:

代码语言:javascript
复制
class A {
private:
    string name;
    int age;

    void init(string name, int age) {
        this->name = name;
        this->age = age;
    }

public:
    A(string name, int age) {
        init(name, age);
    }

    A() {
        init("bob",20);
    }

    void print() {
        cout << name << " " << age << endl;
    }
    // ...
    // ...
};

此时输出就正常了,这种方案比较简单,相信搭建也明白是什么意思,就不多阐述了,重点阐述第二种方案!

1.2 定点new

new的另一种new的表达式,定点new表达式(placement new),它的作用是在已分配的原始内存中初始化一个对象,它与new的其他版本不同之处在于它并不分配内存。

表达式的原型如下:

代码语言:javascript
复制
new (place_address) type

因此到这里可以使用如下:

代码语言:javascript
复制
new(this)A("bob", 20);

最后的完整代码:

代码语言:javascript
复制
class A {
private:
    string name;
    int age;
public:
    A(string name, int age) {
        this->name = name;
        this->age = age;
    }

    A() {
        new(this)A("bob", 20);
    }

    void print() {
        cout << name << " " << age << endl;
    }
    // ...
    // ...
};

输出:

代码语言:javascript
复制
bob 20

总结:针对构造互调两种方法解决:

  • 定点new
  • 封装到成员函数,推荐为private函数。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0.导语
  • 1.构造互调两方案
    • 1.1 封装方案
      • 1.2 定点new
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档