C ++初始化指针/引用/复制细微差别

时间:2017-07-25 17:46:39

标签: c++ copy-constructor initializer-list

上下文:嵌入式编程和初始化列表的细微差别,尤其是我认为应该调用复制构造函数的细微差别。

问题:在另一个类的初始化列表中实例化一个类以初始化一个值保持的成员变量是否会调用复制构造函数? 下面提供的示例,其中TestClassCopy具有由值而不是指针或引用保持的成员变量TestMember。在提供的示例中,cppreference page似乎没有充分涵盖这一点。

加分问题:初始化列表中调用的复制构造函数是否会产生任何时间/空间性能影响?如果C ++规范允许,似乎编译器应该能够优化它。

这里是代码(使用VS2015工具链进行测试):

TestMember.h (由于空间原因未显示TestMember.cpp)

#pragma once

#include <stdint.h>

class TestMember {
public:
    TestMember(uint8_t);

private:
    uint8_t m_value;
};

TestClassCopy.h

#pragma once

#include "test_member.h"

class TestClassCopy {
public:
    TestClassCopy();
    virtual ~TestClassCopy();

private:
    TestMember m_member;
};

TestClassCopy.cpp

#include "test_class_copy.h"

TestClassCopy::TestClassCopy() :
    m_member(TestMember(255)) { // invokes copy constructor yes?
}

TestClassCopy::~TestClassCopy() {
}

为了完整性,我可能做出假设的其他事情我不应该

对于指向TestMember的成员指针,一个新的&#39;在初始化列表中,并删除&#39;在析构函数中就足够了。

对于成员参考,我的理解是,如果将引用传递给构造函数,则可以分配它(因为生命周期在初始化程序列表之外进行管理),因此更具细微差别。 但是,如果TestMember在初始化程序列表中实例化(进入参考),那么在初始化完成后,TestMember临时消失后,这就是禁止。

TestMemberReference.h

#pragma once

class TestMember;

class TestClassReference {
public:
    TestClassReference();
    virtual ~TestClassReference();

private:
    TestMember& m_member;
};

TestMemberReference.cpp

#include "test_class_reference.h"

#include "test_member.h"

TestClassReference::TestClassReference() :
    m_member(TestMember(255)) { // ew, don't do this; TestMember temporary will go out of scope
}

TestClassReference::~TestClassReference() {
}

1 个答案:

答案 0 :(得分:0)

  

这个cppreference page似乎没有在提供的示例中充分涵盖这一点

cppreference页面说“使用direct initialization初始化由类或标识符命名的基类或成员”,如果单击它,则可以读取,从C ++ 17开始,

  

如果初始化程序是一个prvalue表达式,其cv-unqualified类型与T是同一个类,则初始化程序表达式本身,而不是从中实现的临时表达式,用于初始化目标对象:请参阅copy elision

所以答案是:在C ++ 17中没有调用复制构造函数。在C ++ 17之前,可以从技术上调用复制构造函数,但复制省略消除了该调用。您可以通过使用g++ -fno-elide-constructors -O0 -std=c++14

编译示例来观察它,作为证明