7.1如果没有公共拷贝构造函数,C ++编译器不会捕获基类引用 [英] 7.1 C++ compiler doesn't catch base class reference without public copy constructor

查看:77
本文介绍了7.1如果没有公共拷贝构造函数,C ++编译器不会捕获基类引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Visual C ++ .NET 2003(仅限)编译时,下面的程序将中止,就像没有匹配的catch子句一样。如果A的复制构造函数是公共的,它会成功捕获异常。如果我在调试/汇编模式下进入__CxxThrowException,它看起来像编译器创建的pThrowInfo参数从pCatchableTypeArray中排除了typeid(A)。由于无法访问的复制构造函数而未能按值捕获A是合理的,但应该可以通过引用捕获A.看起来像新编译器中的错误


-

Andrew Scheple

aschepler。在 。 mrcday。没有垃圾邮件 。点。 co $>
-


#include< iostream


A级

公共

A(){

虚拟~A(){

保护

A(const A&) {

}


B级:公共A

公开

B(){

虚拟~B(){

B(const B&){

}


int main ()

尝试

抛出B()

} catch(A&)

std :: cout< ;< 抓住一个物体 << std :: endl

返回1


返回0

When compiled with Visual C++ .NET 2003 (only), the program below aborts as though no matching catch clause is present. If the copy constructor of A is made public, it successfully catches the exception instead. If I step into __CxxThrowException in debug/assembly mode, it looks like the pThrowInfo parameter created by the compiler excluded typeid(A) from pCatchableTypeArray. It would be reasonable to fail to catch A by value because of the inaccessible copy constructor, but it should be possible to catch A by reference. Looks like a bug in the new compiler

--
Andrew Scheple
aschepler . at . mrcday . nospam . dot . co
--

#include <iostream

class A
public
A() {
virtual ~A() {
protected
A(const A&) {
}

class B : public A
public
B() {
virtual ~B() {
B(const B&) {
}

int main()
try
throw B()
} catch (A&)
std::cout << "Caught an A object" << std::endl
return 1

return 0

推荐答案

Andrew Schepler< an ******* @ discussion.microsoft.com>写道:
Andrew Schepler <an*******@discussions.microsoft.com> wrote:
使用Visual C ++ .NET 2003(仅限)编译时,下面的程序将中止,就好像没有匹配的catch子句一样。如果A的
复制构造函数被公开,它会成功捕获
异常。如果我在调试/汇编模式下进入__CxxThrowException,它看起来像编译器创建的pThrowInfo参数从pCatchableTypeArray中排除了typeid(A)。
未能捕获A是合理的由于
无法访问的拷贝构造函数的值,但应该可以通过引用来捕获A.看起来像新编译器中的错误。


AFAIK例外必须有公开复制件

ctors,否则该程序会形成错误的b $ b。我认为编译器

应该发出错误,但我恐怕

这是QoI问题而不是必需的。

Andrew Schepler
When compiled with Visual C++ .NET 2003 (only), the program below
aborts as though no matching catch clause is present. If the
copy constructor of A is made public, it successfully catches the
exception instead. If I step into __CxxThrowException in
debug/assembly mode, it looks like the pThrowInfo parameter
created by the compiler excluded typeid(A) from pCatchableTypeArray.
It would be reasonable to fail to catch A by value because of the
inaccessible copy constructor, but it should be possible to
catch A by reference. Looks like a bug in the new compiler.
AFAIK exceptions must have public copy
ctors, otherwise the program is ill-
formed. I''d think that the compiler
should issue an error, but I am afraid
this is a QoI issue and not required.
Andrew Schepler




Schobi


-
Sp ****** @ gmx.de 永远不会被阅读

我是Schobi at suespammers dot org


有时编译器比人们更合理。

Scott Meyers



Schobi

--
Sp******@gmx.de is never read
I''m Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers


--- - Hendrik Schober写道:----
----- Hendrik Schober wrote: ----
AFAIK例外必须有公共警察,否则该程序生病了
形成。我认为编译
应该发出错误,但我是afrai
这是一个QoI问题而不是必需的
AFAIK exceptions must have public cop
ctors, otherwise the program is ill
formed. I''d think that the compile
should issue an error, but I am afrai
this is a QoI issue and not required




我不是真的买这个,我仍然认为它是编译器错误的b
编译器错误。我无法访问标准

但这里有一些我的推理


1.公共,受保护和私有关键字ar

显然是为了控制编译时行为

,对结果代码的更改尽可能少

(有一个结构的警告具有混合访问权限

类别的数据不应该看起来像C中的山姆

。如果使一个函数受到保护会打破某些纯粹的C ++,那么它应该在编译时打破,而不是在运行时打破


2.函数问题永远不会成为

(使用任何正常工作的编译器,或者如果我们将公告改为
)。我本来可以把它私有化

并保持未定义。一个异常对象应该有一个公共拷贝构造函数,因为总是需要使用thro

语句来复制(unles

返回值优化适用?),但是这里的例外

对象是B类,而不是A,而B''s警察

构造函数是公共的


3.编译器有机会抱怨我将会因为异常处理机制调用A的复制构造函数而导致
。如果w />


B b

A& a = b

抛出一个

然后需要使用throw语句来生成一个

对象,切片b并抛出它。这可能足够

来尊重A'的复制构造的可访问性

来自投掷的上下文。如果我们有
抓住(按价值而不是按参考价格计算
,则必须提供一份
异常对象的副本初始化ai

catch块,无论是异常对象itsel

实际上是A还是B.所以这可能应该是b $ b尊重可访问性从捕获的上下文

再次重复一遍,所有这些都可以由编译器而不是运行时来承担



4.我对数据内部异常的检查 - 相关

函数传递似乎表明

在throw语句中,编译器创建了

符号它表示抛出信息B

包含一个type_info指针数组

符号表示可捕获的B类型。并且/>
A的拷贝构造函数是不可访问的,typeid(A

从该数组中省略。虽然它确实是真的,但是
a全球F不能用价值来抓住A,那里很难

似乎有任何理由不予考虑。在
抛出语句中,编译器不知道谁会抓住它 - 可能是通过引用 - 或者可能是通过引用来获得
但是在A或B的成员或朋友的功能中,除非编译器能够生成多个

B的可捕获类型。事情,它会表现得很精致

相同即使投掷和捕获都是我的成员A.在我的原始计划中

发现这个,相当于A继承了

std :: exception,而我正在抛出B并尝试

来捕获std :: exception& ;,两者都有publi

复制构造函数,但A stoppe的可访问性

编译器搜索类继承器

并且异常拒绝捕获为std ::例外&

那么微软是否需要完全改变
机制,或者添加标记以跟踪物品可能被价值捕获的物品?
不,简单的

修复是始终将基类视为''catchable

并且只是检查投票状态下的可访问性

和如果按价值收取声明


-

Andrew Scheple

aschepler。在 。 mrcday。没有垃圾邮件 。点。



I don''t really buy this, and I still think it''s
compiler bug. I don''t have access to the Standard
but here''s some of my reasonings

1. The public, protected, and private keywords ar
clearly intended to control compile-time behavior
with as few changes to the resulting code as possible
(There is the caveat that a struct with mixed acces
classes for its data shouldn''t be expected to look the sam
in C). If making a function protected is going to break somethin
purely C++, it should break at compile-time, not at run-time

2. The function in question would never be calle
(using any working compiler or if we changed i
to public). I could have just as well made it privat
and left it undefined. An exception object shoul
have a public copy constructor since the thro
statement is always required to make a copy (unles
the return value optimization applies?), but the exceptio
object here is of class B, not A, and B''s cop
constructor is public

3. The compiler gets opportunities to complain i
situations where the copy constructor of A would b
called by the exception-handling mechanisms. If w
have
B b
A& a=b
throw a
then the throw statement is required to make an
object, slicing b, and throw it. This probably ough
to respect the accessibility of A''s copy constructo
from the context of the throw. And if we hav
catch (A a
by value instead of by reference, then a copy of th
exception object must be made to initialize a i
the catch block, whether the exception object itsel
was really an A or a B. So this probably ought t
respect accessibility from the context of the catch
And to repeat myself again, all this can be don
by the compiler rather than the runtime

4. My inspection of the data internal exception-relate
functions are passing around seems to indicat
that at the throw statement, the compiler creates
symbol it mangles suggesting "throw info for B
containing an array of type_info pointers with
symbol suggesting "catchable types for B". And whe
the copy constructor for A isn''t accessible, typeid(A
gets omitted from that array. Though it''s true tha
a global function can''t catch A by value, there hardl
seems to be any reason to leave it out. At th
throw statement, the compiler has no clue who migh
be catching it---maybe by reference, or mayb
by value but in a member of A or B or a friend function
Plus, unless the compiler can generate multipl
"catchable types for B" things, it will behave exactl
the same even if both the throw and catch are i
members of A. In my original program where
discovered this, the equivalent of A inherite
std::exception, and I was throwing B and attemptin
to catch std::exception&, both of which had publi
copy constructors, but the accessibility of A stoppe
the compiler from searching up the class inheritanc
and the exception refused to catch as std::exception&
So does Microsoft need to change th
mechanism entirely or add flags to track whethe
the object may be caught by value? No, the simples
fix is to always consider base classes as ''catchable
and just check accessibility at the throw statemen
and at the catch statement if by value

--
Andrew Scheple
aschepler . at . mrcday . nospam . dot . co


Andrew Schepler写道:
Andrew Schepler wrote:
----- Hendrik Schober写道:-----
----- Hendrik Schober wrote: -----
AFAIK例外情况必须有公共副本,否则程序就会形成。我认为编译器应该发出错误,但我担心这是一个QoI问题而不是必需的。
AFAIK exceptions must have public copy
ctors, otherwise the program is ill-
formed. I''d think that the compiler
should issue an error, but I am afraid
this is a QoI issue and not required.



我不知道真的买这个,我还是认为它是编译器的bug。我无法访问标准,
但这里有一些我的推理:



I don''t really buy this, and I still think it''s a
compiler bug. I don''t have access to the Standard,
but here''s some of my reasonings:




抱歉,但Schobi是正确的 - 您的代码不需要按照C ++标准(除了你的推理)工作。


15.3p17说当异常声明指定类类型时,。 ..

复制构造函数和析构函数应该可以在

处理程序的上下文中访问。


制作副本 - 公众继续前进。


-cd



Sorry, but Schobi is correct - your code is not required to work according
to the C++ standard (your reasonings aside).

15.3p17 says "When the exceptiondeclaration specifies a class type, ... The
copy constructor and destructor shall be accessible in the context of the
handler."

Make the copy-ctor public and move on.

-cd



这篇关于7.1如果没有公共拷贝构造函数,C ++编译器不会捕获基类引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆