繁体   English   中英

继承构造函数和虚拟基类

[英]Inheriting constructors and virtual base classes

我即将创建一个异常类层次结构,概念上看起来像这样:

#include <iostream>
#include <stdexcept>

class ExceptionBase : public std::runtime_error {
public: 
    ExceptionBase( const char * msg ) : std::runtime_error(msg) {}
};

class OperationFailure : virtual public ExceptionBase {
public: 
    using ExceptionBase::ExceptionBase;
};

class FileDoesNotExistError : virtual public ExceptionBase {
public: 
    using ExceptionBase::ExceptionBase;
};

class OperationFailedBecauseFileDoesNotExistError
    : public OperationFailure, FileDoesNotExistError {
public: 
    using ExceptionBase::ExceptionBase; // does not compile
};

int main() {
    OperationFailedBecauseFileDoesNotExistError e("Hello world!\n");

    std::cout << e.what();
}

所有构造函数应该与ExceptionBase类的构造函数相同。 派生的异常仅在类型上有所不同,否则没有添加的功能。 上面代码中提到的最后一个异常类型也应该有这些构造函数。 这是否可以使用C ++ 11标准的继承构造函数功能? 如果那是不可能的:还有什么选择?

(顺便说一句:在上面的代码中的类OperationFailureFileDoesNotExistError 。没有用gcc 4.8编译,但铿锵3.4显然,GCC拒绝继承虚拟基础构造这将是有趣的,知道谁在这里两种编译器拒绝class OperationFailedBecauseFileDoesNotExistError ,因为继承构造函数不从直接基础继承。)

using声明用于继承构造函数时,它需要一个直接的基类[namespace.udecl] / 3

如果这样的using-declaration命名一个构造函数,那么nested-name-specifier应该命名一个被定义的类的直接基类; 否则它会引入由成员名称查找找到的声明集。

即在您的情况下, OperationFailedBecauseFileDoesNotExistError中的using声明不继承,但重新声明(作为别名)或取消隐藏ExceptionBase的ctor的名称。

您必须为OperationFailedBecauseFileDoesNotExistError编写一个非继承的ctor。


顺便说一句,这适用于非虚拟基类:继承ctors的using声明被重写为:

//using ExceptionBase::ExceptionBase;

OperationFailure(char const * msg)
: ExceptionBase( static_cast<const char*&&>(msg) )
{}

由于您可能只在mem-initializer-list中初始化直接基类(或虚基类),因此非虚基类限制using-declaration仅从直接基类继承ctors是有意义的。

继承ctors提议的作者已经意识到这打破了对虚拟基类ctors的支持,参见N2540

通常,继承具有虚拟基础的类的构造函数定义将是不正确的,除非虚拟基础支持默认初始化,或虚拟基础是直接基础,并命名为转发的基础。 同样,所有数据成员和其他直接库都必须支持默认初始化,否则任何使用继承构造函数的尝试都将是错误的。 注意:使用时形成不良,未声明。

继承构造函数就像为您指定的所有构造函数引入包装函数。 在您的情况下,您必须调用OperationFailureFileDoesNotExistError的特定构造函数,但引入的包装器将只调用它们中的任何一个。


我刚刚查看了最新的C ++ 11草案 (第12.9节),但它并没有明确涵盖您的案例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM