【发布时间】:2026-01-29 17:20:05
【问题描述】:
我想知道这段代码是否表现出正确的 C++ 行为?
class Foo
{
public:
Foo(std::string name) : m_name(name) {}
Foo(const Foo& other) {
std::cout << "in copy constructor:" << other.GetName() << std::endl;
m_name = other.GetName();
}
std::string GetName() const { return m_name; }
void SetName(std::string name) { m_name = name; }
private:
std::string m_name;
};
Foo CreateFoo(std::string name)
{
Foo result(name);
return result;
}
void ChangeName(Foo& foo)
{
foo.SetName("foofoo");
}
int _tmain(int argc, _TCHAR* argv[])
{
Foo fooA("alan");
std::cout << "fooA name: " << fooA.GetName() << std::endl;
bool b = true;
ChangeName(b ? fooA : CreateFoo("fooB"));
std::cout << "fooA name: " << fooA.GetName() << std::endl;
return 0;
}
在 VS2008 中内置时输出为:
fooA name: alan
fooA name: foofoo
但是当在 VS2010 中构建相同的代码时,它变成:
fooA name: alan
in copy constructor: alan
fooA name: alan
在“alan”上调用了一个复制构造函数,尽管是通过引用传递(或不是根据情况而定),但调用 ChangeName 并没有改变 fooA。
C++ 标准是否发生了变化,Microsoft 是否修复了错误行为或引入了错误?
顺便说一句,为什么要调用复制构造函数?
【问题讨论】:
-
您的代码在我看来格式不正确,因此我不希望您有任何关于它的问题的答案。您希望将引用作为 ChangeName 的参数,但给它一个创建临时的表达式。
-
是的。将警告级别设置为 4 并再次编译。
-
@Noah:或者禁用 VC 编译器中的语言扩展,这将发出一个编译器错误,说明问题所在:
error C2664: 'ChangeName' : cannot convert parameter 1 from 'Foo' to 'Foo &' -
不幸的是,禁用语言扩展与 /fp:fast 冲突 - 虽然技术上可以理解,但并不理想。
-
看到我不得不查一下,这里有关于 Eamon 评论的额外信息,供想要了解更多信息的人使用 - msdn.microsoft.com/en-us/library/e7s85ffb%28VS.80%29.aspx
标签: c++ visual-c++ visual-studio-2010