- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试覆盖基类函数。派生类型和基类型都返回指针,因此根据我在 google 和 stackoverflow 上阅读的一些帖子,它应该是协变的。
但是在 MSVC2013 中有以下类:
class PSBaseObject
{
public:
PSBaseObject() {}
virtual ~PSBaseObject() {}
virtual void* data() { return this; }
virtual const void* data() const { return this; }
};
template<typename T>
class PSObject : public PSBaseObject
{
private:
T* data_;
public:
PSObject(T* object) : data_(object) {}
~PSObject() { delete data_; }
T* data() { return data_; }
const T* data() const { return data_; }
};
我得到一个错误:
'PSObject<data>::data': overriding virtual function return type differs and is not covariant from 'PSBaseObject::data'
数据定义和使用如下:
typedef struct
{
void* hFileMap;
void* pData;
std::size_t size;
} data;
data* info = new data();
auto ptr = new PSObject<data>(info);
为什么不是协变的?
知道我在 MSVC2013
中做错了什么吗?代码在 g++ 4.8.1
中编译并运行良好。
最佳答案
MSVC 是对的; void*
与 T*
不协变。引用标准(10.3 [class.virtual],第 7 节):
The return type of an overriding function shall be either identical to the return type of the overridden function or covariant with the classes of the functions. If a function
D::f
overrides a functionB::f
, the return types of the functions are covariant if they satisfy the following criteria:— both are pointers to classes, both are lvalue references to classes, or both are rvalue references to classes
— the class in the return type of
B::f
is the same class as the class in the return type ofD::f
, or is an unambiguous and accessible direct or indirect base class of the class in the return type ofD::f
— both pointers or references have the same cv-qualification and the class type in the return type of
D::f
has the same cv-qualification as or less cv-qualification than the class type in the return type ofB::f
.
void
不是 T
的基类(= data
),所以返回类型不是协变。
那么为什么要这条规则呢?嗯,这个想法是,如果你有
struct B {
virtual U* f();
};
struct D : B {
virtual V* f();
};
B* b1 = new B();
B* b2 = new D();
U* u1 = b1->f();
U* u2 = b2->f();
b1->f()
将调用 B::f
,它返回 U*
。但是 b2->f()
将调用 D::f
,它返回 V*
。 V
必须从 U
派生,以便从 D::f
返回的 V*
始终可以转换为U*
.
现在,在这种情况下允许 U
为 void
是合理的,因为任何指向对象类型的指针都可以转换为 void*
,即使 void
不是任何对象的基类。但标准并不要求允许。
该标准还说(1.4 [intro.compliance],第 8 段),
A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program. Implementations are required to diagnose programs that use such extensions that are ill-formed according to this International Standard. Having done so, however, they can compile and execute such programs.
所以 g++ 没有错。允许 U
为 void
是一个扩展,它不会改变任何格式良好的程序的行为,而 g++ 会 em> 当您尝试编译此代码时发出警告。
关于c++ - 覆盖虚函数协变返回类型(两个指针),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21963734/
我正在尝试编写一个相当多态的库。我遇到了一种更容易表现出来却很难说出来的情况。它看起来有点像这样: {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE
谁能解释一下这个表达式是如何工作的? type = type || 'any'; 这是否意味着如果类型未定义则使用“任意”? 最佳答案 如果 type 为“falsy”(即 false,或 undef
我有一个界面,在IAnimal.fs中, namespace Kingdom type IAnimal = abstract member Eat : Food -> unit 以及另一个成功
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: What is the difference between (type)value and type(va
在 C# 中,default(Nullable) 之间有区别吗? (或 default(long?) )和 default(long) ? Long只是一个例子,它可以是任何其他struct类型。 最
假设我有一个案例类: case class Foo(num: Int, str: String, bool: Boolean) 现在我还有一个简单的包装器: sealed trait Wrapper[
这个问题在这里已经有了答案: Create C# delegate type with ref parameter at runtime (1 个回答) 关闭 2 年前。 为了即时创建委托(dele
我正在尝试获取图像的 dct。一开始我遇到了错误 The function/feature is not implemented (Odd-size DCT's are not implemented
我正在尝试使用 AFNetworking 的 AFPropertyListRequestOperation,但是当我尝试下载它时,出现错误 预期的内容类型{( “应用程序/x-plist” )}, 得
我在下面收到错误。我知道这段代码的意思,但我不知道界面应该是什么样子: Element implicitly has an 'any' type because index expression is
我尝试将 SignalType 从 ReactiveCocoa 扩展为自定义 ErrorType,代码如下所示 enum MyError: ErrorType { // .. cases }
我无法在任何其他问题中找到答案。假设我有一个抽象父类(super class) Abstract0,它有两个子类 Concrete1 和 Concrete1。我希望能够在 Abstract0 中定义类
我想知道为什么这个索引没有用在 RANGE 类型中,而是用在 INDEX 中: 索引: CREATE INDEX myindex ON orders(order_date); 查询: EXPLAIN
我正在使用 RxJava,现在我尝试通过提供 lambda 来订阅可观察对象: observableProvider.stringForKey(CURRENT_DELETED_ID) .sub
我已经尝试了几乎所有解决问题的方法,其中包括。为 提供类型使用app.use(express.static('public'))还有更多,但我似乎无法为此找到解决方案。 index.js : imp
以下哪个 CSS 选择器更快? input[type="submit"] { /* styles */ } 或 [type="submit"] { /* styles */ } 只是好
我不知道这个设置有什么问题,我在 IDEA 中获得了所有注释(@Controller、@Repository、@Service),它在行号左侧显示 bean,然后转到该 bean。 这是错误: 14-
我听从了建议 registering java function as a callback in C function并且可以使用“简单”类型(例如整数和字符串)进行回调,例如: jstring j
有一些 java 类,加载到 Oracle 数据库(版本 11g)和 pl/sql 函数包装器: create or replace function getDataFromJava( in_uLis
我已经从 David Walsh 的 css 动画回调中获取代码并将其修改为 TypeScript。但是,我收到一个错误,我不知道为什么: interface IBrowserPrefix { [
我是一名优秀的程序员,十分优秀!