gpt4 book ai didi

c++ - 为什么下面的代码在 VS2010 中编译成功?

转载 作者:太空宇宙 更新时间:2023-11-04 15:27:10 25 4
gpt4 key购买 nike

我有以下异常类。

class ExceptionTest : std::exception
{
public:
ExceptionTest(int value):
m_value(value)
{
}
~ExceptionTest()
{
}
private:
ExceptionTest(const ExceptionTest& test)
{
}

int m_value;
};

然后我以这种方式使用它 -

int checkexception()
{
throw ExceptionTest(2);
}

int main()
{
try
{
checkexception();
}
catch (ExceptionTest& exception)
{
cout<<"haha";
}
return 1;
}

即使复制构造函数是私有(private)的,这也能很好地工作。

如果您按值捕获异常,它会失败 -

int main()
{
try
{
checkexception();
}
catch (ExceptionTest exception) --> this fails
{
cout<<"haha";
}
return 1;
}

我得到的错误是

error C2316: 'ExceptionTest' : cannot be caught as the destructor and/or copy   
constructor are inaccessible

如果我没有在类中定义复制构造函数,我会得到一个链接器错误

class ExceptionTest : std::exception
{
public:
ExceptionTest(int value):
m_value(value)
{
}
~ExceptionTest()
{
}
private:
ExceptionTest(const ExceptionTest& test);

int m_value;
};

LINK : C:\Users\sumitha\Documents\Visual Studio 2010\Projects\test\Debug\test.exe 未找到或未由最后一个增量链接构建;执行全链接1>main.obj : error LNK2001: 未解析的外部符号“private: __thiscall ExceptionTest::ExceptionTest(class ExceptionTest const &)” (??0ExceptionTest@@AAE@ABV0@@Z)1>C:\Users\sumitha\Documents\Visual Studio 2010\Projects\test\Debug\test.exe : fatal error LNK1120: 1 Unresolved external ========== 构建:0 成功,1 失败,0 最新,0 跳过 ==========

如果上述情况成立,我们总是可以将异常类的复制构造函数设为私有(private),这样调用者就可以通过引用强制捕获异常。我认为这是因为“返回值优化”而发生的

最佳答案

这似乎是 VS2010 的 C++ 实现中的一个错误。

当您throw 表达式时,会通过复制(或移动)throw 表达式的操作数来创建一个临时异常对象。如果表达式具有类类型,这涉及复制(或移动)构造函数,并且构造函数必须在 throw 点可访问。如果异常对象的复制构造函数是私有(private)的,则该对象只能从成员函数或友元函数中抛出。

这个问题完全独立于异常对象随后在程序中是按值捕获还是按引用捕获。

在构造临时异常对象时,可能会省略实际拷贝,但 C++ 要求本应使用的构造函数仍然可访问。

ISO/IEC 14882:2003 15.1 [except.throw]/5:

If the use of the temporary object can be eliminated without changing the meaning of the program except for the execution of constructors and destructors associated with the use of the temporary object (12.2), then the exception in the handler can be initialized directly with the argument of the throw expression. When the thrown object is a class object, and the copy constructor used to initialize the temporary copy is not accessible, the program is ill-formed (even when the temporary object could otherwise be eliminated). Similarly, if the destructor for that object is not accessible, the program is ill-formed (even when the temporary object could otherwise be eliminated).

尽管抛出表达式现在可以移动而不是在适当的地方复制,但 C++0x 中并未删除此要求。

草案 n3291 15.1 [except.throw]/5:

When the thrown object is a class object, the copy/move constructor and the destructor shall be accessible, even if the copy/move operation is elided (12.8).

关于c++ - 为什么下面的代码在 VS2010 中编译成功?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5840692/

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