gpt4 book ai didi

c++ - 隐式转换和复制构造函数

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

更新:suggested duplicate只解决了这个问题的一部分。那里没有解释了解正在发生的事情的关键(首先创建临时引用的事实)。

这是我第一次使用隐式转换,所以我这样写:

class A {};

class B {
public:
B(A& other) {}
// Copy constructor
B(const B& other) {}
};

int main() {
A foo;
B bar = foo;
}

这会按预期进行编译,但如果我删除 const,我的编译器(gcc 版本 4.8.4)会在分配时产生,并显示一条我无法理解的错误消息:

test.cc: In function ‘int main()’:
test.cc:12:13: error: no matching function for call to ‘B::B(B)’
B bar = foo;
^
test.cc:12:13: note: candidates are:
test.cc:7:5: note: B::B(B&)
B(B& other) {}
^
test.cc:7:5: note: no known conversion for argument 1 from ‘B’ to ‘B&’
test.cc:5:5: note: B::B(A&)
B(A& other) {}
^
test.cc:5:5: note: no known conversion for argument 1 from ‘B’ to ‘A&’

那是有效的 C++ 代码吗?为什么当我试图分配一个 A 开始时它说 no matching function for call to ‘B::B(B)’

最佳答案

这个声明

B bar = foo;

按以下方式工作:

首先,编译器使用构造函数创建一个临时对象:

B(A& other) {}

然后它尝试在复制构造函数中使用这个临时对象:

B(B& other) {}

但它可能不会绑定(bind)具有非常量引用的临时对象,并且它会发出错误。

当您使用等号时,就会使用所谓的复制初始化。

如果你写了

B bar( foo );

那么这里会使用所谓的直接初始化,即不调用拷贝构造函数。在这种情况下,此代码将编译。

考虑到可能会绕过复制/移动构造函数,并且可以直接在目标对象中构建临时对象。这称为复制省略。尽管如此,所有规则都应保留,就好像复制/移动构造函数被显式调用一样。

例如,如果您为类 B 的构造函数添加输出语句

class A {};

class B {
public:
B(A& other) { std::cout << "B::B( A & )" << std::endl; }
// Copy constructor
B(const B& other) { std::cout << "B::B( const B & )" << std::endl; }
};

int main()
{
A foo;
B bar = foo;
}

那么你就不会看到消息了

B::B( const B & )

但是复制构造函数应该是可访问的。

例如,如果您将其设为私有(private)

class A {};

class B {
public:
B(A& other) { std::cout << "B::B( A & )" << std::endl; }
// Copy constructor
private:
B(const B& other) { std::cout << "B::B( const B & )" << std::endl; }
};

int main()
{
A foo;
B bar = foo;
}

程序不会编译(只有当它不是 MS VC++ 编译器时。:))

关于c++ - 隐式转换和复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33439862/

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