无法在从类继承的结构上调用正确的构造函数C++

Can't call correct constructor on struct inherited from C++ class

本文关键字:调用 构造函数 C++ 结构上 继承      更新时间:2023-10-16

我决定尝试使用为面向对象的C++代码开发C包装器API中描述的模型,为V8 API创建一个简单的C包装器。不幸的是,我对C++不太熟悉,所以我遇到了继承构造函数的问题。

v8capi.h

typedef struct V8Context V8Context;
#ifdef __cplusplus
extern "C" {
#endif
V8Context *V8_NewContext();
#ifdef __cplusplus
}
#endif

v8capi.cpp

#include <v8.h>
struct V8Context : public v8::Handle<v8::Context> { };
V8Context *V8_NewContext() {
    v8::HandleScope hscope;
    return new V8Context(v8::Context::New());
}

根据我的理解,new V8Context(...)应该调用v8::Handle<T>的构造函数,该构造函数接受Handle<T>v8::Context::New()返回一个v8::Persistent<T>,它继承了v8::Handle<T>,因此应该可以工作。但实际上,它试图调用一个接受const V8Context &:的构造函数

error C2664: 'V8Context::V8Context' : cannot convert parameter 1 from
'v8::Persistent<T>' to 'const V8Context &'
    with
    [
        T=v8::Context
    ]
    No user-defined-conversion operator available that can perform this
    conversion, or the operator cannot be called

我做错了什么?

V8Context中没有定义构造函数,因此只有隐式复制构造函数作为选项出现。您需要在V8Context中显式定义一个构造函数,该构造函数将v8::Persistent<T>参数转发到其基类。

构造函数不是在C++中继承的(尽管我相信C++11中有一些传递特性),所以您必须在V8Context中编写自己的构造函数,它显式调用正确的基类构造函数。

根据我的理解,new V8Context(...)应该调用v8::Handle<T>的构造函数。

new V8Context(...)将只调用在V8Context中声明的构造函数;构造函数不是继承的。你需要添加一个,类似于:

V8Context(v8::Handle<v8::Context> const & handle) : 
    v8::Handle<v8::Context>(handle) 
{}

new V8Context(...)不从v8::Handle<T>调用构造函数,而是从V8Context调用构造函数。由于您尚未定义构造函数,因此只有默认构造函数和复制构造函数可用(构造函数是不可继承的)。因此,它试图调用复制构造函数,但由于参数无法转换为V8Context而失败。为了解决您的问题,您需要向V8Context添加一个适当的构造函数,它将参数转发到基构造函数(可能不是给定的确切代码,这取决于您的参数看起来有多像,但很相似):

struct V8Context : public v8::Handle<v8::Context> {
  V8Context(const v8::Handle<v8::Context>& handle): v8::Handle<v8::Context>(handle) {}
};

您的V8Context只有编译器生成的构造函数:

  • 复制构造函数,它在需要的时候被合成,并且没有明确声明或使其不可能(例如,通过从没有复制构造函数的类派生)。此构造函数采用V8Cintext作为参数
  • 默认构造函数,当需要时合成,当没有显式构造函数时,所有成员和基都可以默认构造。Thos构造函数没有参数

您试图传递的类型似乎与复制构造函数的签名不匹配。如果你想使用它,你需要显式地提供一个相应的构造函数。