我看到了以下代码段:
class Foo
{
public:
void virtual func() throw (int, float) = 0;
};
class Bar : public Foo
{
public:
void virtual func() throw(short); // line 1: compile error "
// looser throw specifier"
void virtual func() throw(); // line 2: can compile
void virtual func() throw(float, int); // line 3: can compile
void virtual func() throw(float); // line 4: can compile
void virtual func() throw(int); // line 5: can compile
};
int main(void)
{
return 1;
}
Run Code Online (Sandbox Code Playgroud)
Q1>是什么意思
void virtual func() throw (int, float) = 0;
Run Code Online (Sandbox Code Playgroud)
Q2>为什么line1无法通过编译器?
谢谢
让我们打破这个.声明:
void virtual func() throw (int, float) = 0;
Run Code Online (Sandbox Code Playgroud)
有两个你要问的结构.所述=0构建体告诉编译器声明函数是"抽象",它告诉该功能不需要在被限定的编译器class Foo(尽管它可以是-但它通常不是),并且的目的class Foo不能直接创建-无论是作为本地,全球还是通过new.但是,您可以拥有对象的指针或引用class Foo.某些派生类需要将该函数覆盖为非抽象函数 - 可以直接创建该类的对象(只要没有其他抽象函数没有"具体").
该throw (int, float)构造是一个异常规范.这告诉编译器函数的契约是它只会抛出类型的异常,int或者float抛出异常.如果函数抛出其他类型的异常,编译器有义务特别处理(通过调用std::unexpected()).
现在,如果您尝试使用以下声明覆盖派生类中的该函数:
void virtual func() throw(short);
Run Code Online (Sandbox Code Playgroud)
你说的是函数的契约是short如果抛出异常它会抛出类型的异常.但是,throw short不是被覆盖函数的合同的一部分,因此编译器不允许它.
如果你像这样声明覆盖:
void virtual func() throw(float);
Run Code Online (Sandbox Code Playgroud)
你说覆盖可以抛出一个float,这是原始声明的合同的一部分(如果它从不抛出int不破坏合同 - 原始合同只说该函数被允许抛出int,而不是它必须).
标准的相关部分是15.4/3异常规范:
如果虚函数具有异常规范,则在任何派生类中覆盖该虚函数的任何函数的所有声明(包括定义)都应仅允许基类虚函数的异常规范所允许的异常.
注意,标准明确规定,异常规范是不是函数的类型(15.4/12)的一部分,所以一个函数指针可以,例如,指向具有不同异常规格的功能.
您多次定义相同的函数签名.不同的throw()限定符不足以消除功能的歧义.
在throw()预选赛中仅仅意味着特定功能预计只扔在预选赛以下括号中所列的类型.但是,这实际上并不会阻止函数抛出.相反,如果该函数实际上并不抛出任何未上市的类型,你的程序将终止.
| 归档时间: |
|
| 查看次数: |
5437 次 |
| 最近记录: |