gpt4 book ai didi

c++ - 如何强制编译器使用显式复制构造函数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:00:11 25 4
gpt4 key购买 nike

我用一个示例类编写了一个小测试程序,其中还包含自定义构造函数、析构函数、复制构造函数和赋值运算符。当我意识到复制构造函数根本没有被调用时,我感到很惊讶,即使我用我的类的返回值和类似 Object o1; 的行实现了函数。对象 o2(o1);

内部类.hpp:

#include <iostream>

class OuterClass
{
public:
OuterClass()
{
std::cout << "OuterClass Constructor" << std::endl;
}
~OuterClass()
{
std::cout << "OuterClass Destructor" << std::endl;
}
OuterClass(const OuterClass & rhs)
{
std::cout << "OuterClass Copy" << std::endl;
}
OuterClass & operator=(const OuterClass & rhs)
{
std::cout << "OuterClass Assignment" << std::endl;
}

class InnerClass
{
public:
InnerClass() : m_int(0)
{
std::cout << "InnerClass Constructor" << std::endl;
}
InnerClass(const InnerClass & rhs) : m_int(rhs.m_int)
{
std::cout << "InnerClass Copy" << std::endl;
}
InnerClass & operator=(const InnerClass & rhs)
{
std::cout << "InnerClass Assignment" << std::endl;
m_int = rhs.m_int;
return *this;
}
~InnerClass()
{
std::cout << "InnerClass Destructor" << std::endl;
}
void sayHello()
{
std::cout << "Hello!" << std::endl;
}

private:
int m_int;
};

InnerClass innerClass()
{
InnerClass ic;
std::cout << "innerClass() method" << std::endl;
return ic;
}
};

内部类.cpp:

#include "innerclass.hpp"

int main(void)
{
std::cout << std::endl << "1st try:" << std::endl;


OuterClass oc;
OuterClass oc2(oc);
oc.innerClass().sayHello();

std::cout << std::endl << "2nd try:" << std::endl;

OuterClass::InnerClass ic(oc.innerClass());
ic = oc.innerClass();
}

输出:

 1st try:
OuterClass Constructor
OuterClass Copy
InnerClass Constructor
innerClass() method
Hello!
InnerClass Destructor

2nd try:
InnerClass Constructor
innerClass() method
InnerClass Constructor
innerClass() method
InnerClass Assignment
InnerClass Destructor
InnerClass Destructor
OuterClass Destructor
OuterClass Destructor

经过一些研究,我了解到无法保证编译器会使用显式定义的复制构造函数。我不明白这种行为。如果我们不知道它被调用,为什么复制构造函数甚至存在呢?编译器如何决定是否使用它?

或者,更好的是,有没有办法强制编译器使用自定义的复制构造函数?

最佳答案

只是为了与其他答案的完整性,该标准允许编译器在某些情况下省略复制构造函数(其他答案称为“返回值优化”或“命名返回值优化”- RVO/NRVO):

12.8 Copying class objects, paragraph 15 (C++98)

Whenever a temporary class object is copied using a copy constructor, and this object and the copy have the same cv-unqualified type, an implementation is permitted to treat the original and the copy as two different ways of referring to the same object and not perform a copy at all, even if the class copy constructor or destructor have side effects. For a function with a class return type, if the expression in the return statement is the name of a local object, and the cv-unqualified type of the local object is the same as the function return type, an implementation is permitted to omit creating the temporary object to hold the function return value, even if the class copy constructor or destructor has side effects. In these cases, the object is destroyed at the later of times when the original and the copy would have been destroyed without the optimization.

所以在您的 innerClass() 方法中,您可能认为会在返回时调用的复制构造函数被允许优化掉:

InnerClass innerClass() {
InnerClass ic;
std::cout << "innerClass() method" << std::endl;
return ic; // this might not call copy ctor
}

关于c++ - 如何强制编译器使用显式复制构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/793469/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com