C++中如何在一个构造函数中调用另一个构造函数


在java里,经常可见类的构造函数调用另一个构造函数,

但是在c++里,由于构造函数允许有默认参数,使得这种需求大为减少。

虽然这样,也许偶尔我们还是希望在类的构造函数里调用另一个构造函数。

我们知道,构造一个对象时会做两件事:1,分配内存 2,执行构造函数;

所以在构造函数里调用另一个构造函数的关键是让第二个构造函数在第一次分配好的内存上执行,而不是分配新的内存,

这个可以用标准库的placement new做到: 

先看看标准库中placement new的定义 inline void *__cdecl operator new(size_t, void *_P) {return (_P); } 

见没有分配新的内存。 

#include class my { public: my() { new (this) my(5); } my(int i) { a=i; } int a; }; 

使用这个方法需要注意,如果第一个构造函数里初始化了某个成员变量,然后调用另一个构造函数,在

这个构造函数里又初始化了同一个成员变量,这样就会造成同一个成员变量初始化了两次。但

这种问题在java中也存在,编程时注意一下顺序就好了。


在C++中,一个类的构造函数没法直接调用另一个构造函数,比如:


代码块1

  1. #ifndef _A_H_
  2. #define _A_H_
  3. #include <stdio.h>
  4. #include <new>
  5. class A
  6. {
  7. public:
  8.         A()
  9.         {
  10.                 printf("In A::(). m_x=%d\n", m_x);
  11.                 A(0);
  12.                 printf("Out A::(). m_x=%d\n", m_x);

  13.         }


  14.         A(int x)
  15.         {
  16.                 printf("In A::(int x). x=%d\n", x);
  17.                 m_x=x;
  18.         }

  19. private:
  20.         int m_x;
  21. };

这里第11行的调用A(0);只是构建了一个A的临时对象,并没有调用A(int x)来初始化自己。其运行结果是:

代码块2

  1. [root@tivu25 utcov]# ./UTest.out 
    In A::(). m_x=4268020
    In A::(int x). x=0
    Out A::(). m_x=4268020
可以看到尽管调用了A(0),m_x仍然没有改变,是4268020.
正确的方法是使用placement new:


代码块3

  1. //A.h
  2. #ifndef _A_H_
  3. #define _A_H_
  4. #include <stdio.h>
  5. #include <new>
  6. class A
  7. {
  8. public:
  9.         A()
  10.         {
  11.                 printf("In A::(). m_x=%d\n", m_x);
  12.                 new(this) A(0);
  13.                 printf("Out A::(). m_x=%d\n", m_x);

  14.         }


  15.         A(int x)
  16.         {
  17.                 printf("In A::(int x). x=%d\n", x);
  18.                 m_x=x;
  19.         }


  20. private:
  21.         int m_x;
  22. };

  23. #endif

第11行应为: new(this) A(0); 也就是用当前对象来调用构造函数A(int x)构建一个“新”对象。其运行结果是:

代码4

  1. [root@tivu25 utcov]# ./UTest.out 
  2. In A::(). m_x=4268020
  3. In A::(int x). x=0
  4. Out A::(). m_x=0

可以看出,当前对象确实被改变了。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值