没有默认构造函数的初始化赋值
Assignment at Initialization without Default Constructor
在这个程序中,我完全理解为什么主函数的第一部分失败了,需要注释——在我在TestingClass中实现了值变量之后,没有隐式的默认变量。完美的逻辑。然而,我有点惊讶地发现第二部分(创建test2对象)非常成功,至少在gcc 4.8.4中是这样。
#include <iostream>
using namespace std;
class TestingClass
{
public:
TestingClass(int inVal)
{
val = inVal;
}
int val;
};
TestingClass testingCreator()
{
return TestingClass(100);
}
int main()
{
/*
TestingClass test1;
test1 = testingCreator();
cout << "Test1: " << test1.val << endl;
*/
TestingClass test2 = testingCreator();
cout << "Test2: " << test2.val << endl;
}
考虑一下,这也是有道理的,因为对象test2如果没有被构造/初始化就不会存在,但是大多数人认为这样的初始化只是一行的声明和赋值。显然,初始化比这更特殊,因为这段代码可以工作。
这是标准c++吗?它能保证跨编译器工作吗?我感兴趣的是如何初始化以这种方式是不同于只是声明(使用默认的actor),然后分配(通过在全局函数中创建的临时对象)。
UPDATE:添加了一个复制操作符和第三个明显使用复制操作符的case。
#include <iostream>
using namespace std;
class TestingClass
{
public:
TestingClass(const TestingClass &rhs)
{
cout << "In copy ctor" << endl;
this->val = rhs.val + 100;
}
TestingClass(int inVal)
{
val = inVal;
}
int val;
};
TestingClass testingCreator()
{
return TestingClass(100);
}
int main()
{
/*
TestingClass test1;
test1 = testingCreator();
cout << "Test1: " << test1.val << endl;
*/
TestingClass test2 = testingCreator();
cout << "Test2: " << test2.val << endl;
TestingClass test3(test2);
cout << "Test3: " << test3.val << endl;
}
这个输出:Test2: 100
In copy ctor
Test3: 200
UPDATE 2:已经很长时间了,但是碰巧遇到了我的这个老问题,我想我应该添加这个以防其他人在这里结束。如下面的答案所述,正在使用复制构造函数,但省略了对复制函数的实际调用,因此"副作用"(具体地说,是"在复印件上"的印刷);也不执行通过添加100来修改值的操作。为了证明这一点,您可以指定g++命令行参数-fno-elide-constructors
,它将防止省略发生。当使用该标志编译时,示例的输出是:
In copy ctor
In copy ctor
Test2: 300
In copy ctor
Test3: 400
一般情况下,您可能不想使用该标志,但在试图理解构造函数省略的幕后发生的事情时,它可能很有用。正如许多关于该主题的引用所指出的那样,这显然是为什么您的复制函数除了复制之外什么都不做的原因-如果使用构造函数省略,则可能不会执行任何其他副作用。在我的示例中,我在复制因子中有两个副作用,并且它们在执行期间没有执行,因此避免复制因子中的副作用是一个很好的建议,因为结果可能会让一些人感到惊讶。
你对TestingClass test2 = testingCreator();
的想法是有缺陷的。当你看到
type name = stuff;
不能先创建name
,再分配给stuff
。你所做的就是从stuff
复制初始化name
。这意味着调用复制或移动构造函数。一般来说,这个调用可以通过优化编译器来忽略,但如果不是这样,那么这就是您将看到的。在这两种情况下,都不会调用默认构造函数。
在第一个例子中
TestingClass test1;
强制调用默认构造函数,由于您没有默认构造函数,因此会得到一个错误。
test2
由TestingClass
的复制构造函数定义,以testingCreator
的结果作为参数。复制构造函数TestingClass::TestingClass(const TestingClass&)
由编译器自动生成,c++标准保证它复制val
字段。
- 初始化右值引用成员
- 如何初始化所有值相同的 2D 数组?
- C++ 在循环中添加计数器变量并再次初始化其值
- HBOEHM 垃圾回收器未初始化的值错误和泄漏
- 复合赋值的左侧表达式是未初始化的值.计算出的值也将是垃圾
- Valgrind:使用atomic::compare_exchange_weak时,条件跳转或移动取决于未初始化的值
- 初始化器值太多
- 回文程序和条件跳转或移动取决于未初始化的值
- 访问未初始化的值,很可能在向量中
- 为什么使用此奇怪的调用来初始化会员值的类中此功能
- 指针的数组要分类对象和初始化成员值
- 未初始化的值是由堆分配创建的:Unordered_map
- 未初始化的值是由堆栈分配 - Qt - C++创建的
- 条件跳转或移动取决于函数调用中未初始化的值
- 是否可以在一行中初始化一个值递增的向量
- 指针向量,其元素用new初始化:赋给新值时会发生什么
- 如何使我的向量类支持直接初始化/赋值
- 没有默认构造函数的初始化赋值
- C++11:类初始化赋值顺序的主体
- 通过显式调用类构造函数与默认初始化+赋值运算符来使用对象