参考:https://mp.weixin.qq.com/s/0wKTdGK_3JrqyJ4MZy7okA
一个带参数的构造函数,当默认构造去调这个带参数的构造:
#include<iostream>
using namespace std;
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;
}
// ...
// ...
};
int main()
{
A a;
a.print();
}
运行结果:3221225477,一堆垃圾值。。。
这段代码输出的是一个不确定的值,name与age的值并不是我们期待的,原因在于执行A(“bob”, 20)时,并不是用这一构造函数来初始化当前的内存区,而是初始化了一个临时对象的内存区。
具体阐述:A a;这里已经为a分配了内存,然后调用默认构造函数,但是默认构造函数还未执行完,却调用了另一个构造函数,这样相当于产生了一个匿名的临时A对象,它调用A(“bob”, 20)构造函数,将这个匿名临时对象自己的数据成员name与age初始化后,当执行完这一行,这个匿名临时对象已经被释放掉了,此时a的数据成员并没有得到初始化。于是a的name与age是未初始化的,因此其值也是不确定的。
那么如何在C++中实现构造函数调用构造函数呢?
两种方案,第一种:封装到公共操作到私有函数中;第二种:定点new;
1、封装方案
将原来的代码改写:
#include<iostream>
using namespace std;
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;
}
// ...
// ...
};
int main()
{
A a;
a.print();
}
2、定点new
new的另一种new的表达式,定点new表达式(placement new),它的作用是在已分配的原始内存中初始化一个对象,它与new的其他版本不同之处在于它并不分配内存。
表达式的原型如下:
new (place_address) type
因此到这里可以使用如下:
new(this)A(“bob”, 20);
代码如下:
#include<iostream>
using namespace std;
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;
}
// ...
// ...
};
int main()
{
A a;
a.print();
}
总结:针对构造互调两种方法解决:
一、定点new。
二、封装到成员函数,推荐为private函数。
684

被折叠的 条评论
为什么被折叠?



