我有两个类:OuterClass和InnerClass。 InnerClass是OuterClass的私有成员,应该使用InnerClass(int)构造函数在OuterClass构造函数中创建,但仍然会调用默认的InnerClass构造函数。
InnerClass.hpp:
#ifndef INNERCLASS_HPP_
#define INNERCLASS_HPP_
class InnerClass {
public:
int a;
InnerClass();
InnerClass(int);
~InnerClass();
};
#endif /* INNERCLASS_HPP_ */
InnerClass.cpp:
#include "InnerClass.hpp"
#include <iostream>
InnerClass::InnerClass() {
a = 1;
std::cout << "inner class constructed, a = " << a << std::endl;
}
InnerClass::InnerClass(int x) {
a = x;
std::cout << "inner class constructed, a = " << a << std::endl;
//automatically: object InnerClass (a=3) is destroyed here...
}
InnerClass::~InnerClass() {
std::cout << "inner class destructed, a = " << a << std::endl;
}
OuterClass.hpp:
#ifndef OUTERCLASS_HPP_
#define OUTERCLASS_HPP_
#include "InnerClass.hpp"
class OuterClass {
private:
InnerClass blah;
public:
OuterClass();
~OuterClass();
void doSth();
};
#endif /* OUTERCLASS_HPP_ */
OuterClass.cpp:
#include "OuterClass.hpp"
#include <iostream>
OuterClass::OuterClass() {
// automatically: blah = InnerClass();
std::cout << "outer class constructing started, blah.a = " << blah.a << std::endl;
blah = InnerClass(3);
std::cout << "outer class constructed" << std::endl;
}
OuterClass::~OuterClass() {
std::cout << "outer class destructed" << std::endl;
}
void OuterClass::doSth() {
std::cout << "doSth: " << blah.a << std::endl;
}
主:
#include "OuterClass.hpp"
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Compiled at " << __TIME__ << std::endl;
OuterClass x = OuterClass();
x.doSth();
std::cout << "done" << std::endl;
}
输出:
Compiled at 12:11:12
inner class constructed, a = 1 //this is unexpected
outer class constructing started, blah.a = 1 //this should be random data
inner class constructed, a = 3
inner class destructed, a = 3 //this is unexpected
outer class constructed
doSth: 3
done
outer class destructed
inner class destructed, a = 3
问题:
答案 0 :(得分:4)
在构造函数中使用initializer-list。
OuterClass::OuterClass() : blah(3) {
// automatically: blah = InnerClass();
std::cout << "outer class constructing started, blah.a = " << blah.a << std::endl;
std::cout << "outer class constructed" << std::endl;
}
因为你使用
OuterClass::OuterClass() {
// automatically: blah = InnerClass();
std::cout << "outer class constructing started, blah.a = " << blah.a << std::endl;
blah = InnerClass(3);
std::cout << "outer class constructed" << std::endl;
}
首先将初始化blah称为默认c-tor,并在blah = InnerClass(3);
中创建临时对象并将其复制为blah,此字符串将被称为临时对象的析构函数。
答案 1 :(得分:2)
1)为什么在OuterClass构造函数的开头调用InnerClass的默认构造函数?
构建blah
。
2)在OuterClass构造函数中破坏了什么以及为什么(“内部类被破坏,a = 3 //这是意料之外的”)?
您在构造函数的第二行中构造的InnerClass(3)
。您用来保存分配给blah
的值的那个。它被破坏,因为一旦blah
的分配完成,它就会超出范围。
3)似乎在OuterClass构造函数中破坏了具有a = 3的InnerClass对象,而为什么方法doSth()返回3而不是随机数据?
因为您已将值3
分配给blah
。你的代码是:
blah = InnerClass(3);
这会创建一个值为3的InnerClass,然后将其值复制到blah
。因此blah
和此临时对象都具有相同的值。然后将临时销毁。
如果你考虑一下,没有其他合理的方法来实现这一行代码。
4)为什么删除一个InnerClass()构造函数(来自InnerClass.hpp和InnerClass.cpp文件)导致OuterClass.cpp文件中的OuterClass构造函数出现编译时错误?错误说没有找到InnerClass()定义。
因为那时你无法构建blah
。 (正如其他人所指出的那样,你可能想要一个初始化列表来构造blah
,而不是默认构造它,然后不得不去扭曲修复它。)
答案 2 :(得分:0)
OuterClass::OuterClass() /* default blah constructor is called here */ {
std::cout << "outer class constructing started, blah.a = " << blah.a << std::endl;
blah = InnerClass(3); /* a temporary InnerClass is created */
std::cout << "outer class constructed" << std::endl;
} //temporary InnerClass destroyed (out of scope)
使用initializer list
来阻止调用默认构造函数,因为ForEveR建议
答案 3 :(得分:0)
当OuterClass的构造函数开始执行主体时,必须构造所有成员。由于存在blah
InnerClass成员,因此构建了它。
在OuterClass :: OuterClass()中分配给blah
时,会创建一个临时实例。这是事情的顺序:
blah
。从2开始:blah在上面#2中提到的作业中设置为3。
有人推断,在C ++中,如果你有一个专门的参数 - 采用构造函数声明,那么编译器就不会在你的背后创建默认构造函数了。我现在无法深入研究标准中的相关位置,编辑可以随意纠正这一点。
如果您按如下方式对InnerClass进行了检测,它会帮助您:
保留一个静态实例计数器,并将其复制到每个实例。这样你就可以知道哪个实例正在报告。
手动编写InnerClass & operator=(const InnerClass &)
以查看何时调用。
答案 4 :(得分:0)
(PS:你是不是有机会从Java World转到C ++?)
输出说明:
inner class constructed, a = 1 //this is unexpected
使用默认构造函数
构造InnerClassouter class constructing started, blah.a = 1 //this should be random data
这是使用默认ctor
在上一步中构造的InnerClass的值inner class constructed, a = 3
使用重载的ctor构造一个临时的InnerClass并分配给blah成员(调用隐式operator = - 你可以通过重载operator =来检查)
inner class destructed, a = 3 //this is unexpected
上一步中创建的临时InerClass被销毁
outer class constructed
doSth: 3
done
outer class destructed
inner class destructed, a = 3
<强>数目:强>
为什么在开始时调用InnerClass的默认构造函数 OuterClass构造函数?
因为你有InnerClass成员。你应该把它作为指针或使用初始化列表。
OuterClass::OuterClass()
: blah(3)
{
// automatically: blah = InnerClass();
std::cout << "outer class constructing started, blah.a = " << blah.a << std::endl;
// blah = InnerClass(3);
std::cout << "outer class constructed" << std::endl;
}
什么和为什么在OuterClass中被破坏 构造函数(“内部类被破坏,a = 3 //这是意料之外的”)?
临时的InnerClass在这里被销毁。
似乎在a = 3中破坏了具有= 3的InnerClass对象 OuterClass构造函数,为什么方法doSth()返回3 而不是随机数据?
blah成员现在有一个值为3的InnerClass对象的副本
为什么删除InnerClass() 构造函数(来自InnerClass.hpp和InnerClass.cpp文件) 导致在OuterClass构造函数中的编译时错误 OuterClass.cpp文件?错误说没有InnerClass()定义 找到。
您的意思是删除默认构造函数。是的,错误是预期的,因为首先使用默认ctor创建了blah成员。