c++报错invalid new-expression of abstract class type和cannot declare field "" to be of abstract type""

本文深入探讨了C++中抽象类的使用及其与虚函数的关系,解析了常见错误如“invalid new-expression of abstract class type”和“cannot declare field to be of abstract type”的原因与解决方案。通过具体代码示例,讲解了如何正确实现抽象类和虚函数,以及如何避免常见的编程陷阱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 报错信息一invalid new-expression of abstract class type
    基类纯虚函数
virtual double getArea()=0;

然而子类重写虚函数:

virtual double getArea() const{
        return PI*radius*radius;
    }

所以报错原因是纯虚函数没有加const,或者子类虚函数去掉const,两者须保持一致,否则不可被认定为重写虚函数。

错误代码:

#include<iostream>

#define PI 3.1415926
using namespace std;

class Geometry {
public:
    virtual double getArea() const = 0;
};

class Circle : public Geometry{
public:
    Circle(double rad):radius(rad){}
    virtual double getArea() const{
        return PI*radius*radius;
    }
private:
    double radius;
};

class Pillar{
public:
    double getVolume(){
        return bottom.getArea()*height;
    }
private:
    Geometry bottom; //错误处, 改为Geometry *bottom;
    double height;
};

关键点:

 Geometry bottom; //错误处
 Geometry *bottom;//正确

完整正确及测试代码:

#include<iostream>

#define PI 3.1415926
using namespace std;

class Geometry {
public:
    virtual double getArea() const = 0;
};

class Circle : public Geometry{
public:
    Circle(double rad):radius(rad){}
    ~Circle(){}
    virtual double getArea() const{
        return PI*radius*radius;
    }
    double getRadius() const{
        return radius;
    }
private:
    double radius;
};

class Rectangle : public Geometry{
public:
    Rectangle(double len,double wid):length(len),width(wid){}
    ~Rectangle(){}
    virtual double getArea() const{
        return length*width;
    }
    double getLength() const{
        return length;
    }
    double getWidth() const{
        return width;
    }
private:
    double length;
    double width;
};
class Pillar{
public:
    double getVolume(){
        return bottom->getArea()*height;
    }
	Pillar(Geometry*geometry,double height):bottom(geometry),height(height){}
	void setButtom(Geometry*geometry){
		this->bottom = geometry;
	}
	void setHeight(double height){
		this->height = height;
	}
	double getHeight(){
		return height;
	}
	double getArea() const{
		return bottom->getArea();
	}
private:
    Geometry* bottom;
    double height;
};
int main(){
	int height = 5;
    Geometry* geometry = new Rectangle(3.0,4.0);
	Pillar pillar(geometry,height);
    cout<<"长方体面积是"<<pillar.getVolume()<<endl;
	geometry = new Circle(3.0);
    pillar.setButtom(geometry);
    cout<<"圆柱面积是"<<pillar.getVolume()<<endl;
    return 0;
}
<think>我们正在解决一个关于ESP32BLE项目中的编译错误。错误信息是:"invalidnew-expressionofabstractclasstypeSecurityCallbacks"。这个错误通常发生在尝试实例化一个抽象类时,因为抽象类中包含纯虚函数(purevirtualfunction)没有被完全实现。在ESP32的BLE安全回调中,`SecurityCallbacks`是一个抽象基,它定义了一些纯虚函数,要求派生必须实现这些函数。如果我们在派生中没有实现所有的纯虚函数,那么这个派生也会被视为抽象类,因此不能实例化。根据引用[2]中提到的BLE初始化代码,我们可能需要实现`SecurityCallbacks`的所有纯虚函数。步骤:1.确定`SecurityCallbacks`中定义了哪些纯虚函数。通常,这些函数包括:-`onPasskeyRequest`-`onPasskeyNotify`-`onSecurityRequest`-`onKeyExchange`-`onAuthenticationComplete`-等等(具体取决于ESP-IDF版本)2.创建一个继承自`SecurityCallbacks`的,并实现所有这些纯虚函数。3.在设置BLE安全回调时,使用这个派生的实例。示例代码:假设`SecurityCallbacks`的定义如下(具体以实际头文件为准):```cppclassSecurityCallbacks{public:virtual~SecurityCallbacks()=default;virtualuint32_tonPasskeyRequest()=0;virtualvoidonPasskeyNotify(uint32_tpasskey)=0;virtualboolonSecurityRequest()=0;virtualvoidonAuthenticationComplete(esp_ble_auth_cmpl_tcmpl)=0;//...可能还有其他函数};```我们需要创建一个派生,例如`MySecurityCallbacks`,并实现所有纯虚函数:```cppclassMySecurityCallbacks:publicSecurityCallbacks{public:uint32_tonPasskeyRequest()override{//返回一个固定的密码,或者根据需要生成return123456;}voidonPasskeyNotify(uint32_tpasskey)override{//处理密码通知ESP_LOGI(TAG,"ThepasskeyNotifynumber:%d",passkey);}boolonSecurityRequest()override{//处理安全请求,返回true表示接受ESP_LOGI(TAG,"SecurityRequest");returntrue;}voidonAuthenticationComplete(esp_ble_auth_cmpl_tcmpl)override{//认证完成ESP_LOGI(TAG,"AuthenticationComplete:%s",cmpl.success?"Success":"Fail");if(cmpl.success){//认证成功后的操作}}};```然后,在设置BLE安全回调时,使用这个派生的实例:```cpp//在初始化BLE之后BLEDevice::setSecurityCallbacks(newMySecurityCallbacks());```注意:确保在堆上创建对象(使用`new`),因为`setSecurityCallbacks`通常接受一个指针,并负责在适当的时候删除它(但请检查文档确认内存管理方式)。如果错误仍然存在,请检查是否遗漏了任何纯虚函数的实现。可以通过查看编译器错误信息来确定哪些函数没有被实现。另外,请注意ESP-IDF的版本,不同版本的BLE库可能会有不同的`SecurityCallbacks`定义。建议查看当前使用的ESP-IDF版本中`SecurityCallbacks`的实际定义(在头文件中),确保实现了所有纯虚函数。如果问题还未解决,请提供具体的代码片段,以便进一步分析。§§相关问题§§1.如何查看ESP-IDF中`SecurityCallbacks`的定义?2.BLE安全回调中各个函数的作用是什么?3.在ESP32BLE项目中,如何设置安全连接参数?</think>### 修复ESP32 BLE "invalid new-expression of abstract class type SecurityCallbacks" 错误 这个编译错误表明在实例化`SecurityCallbacks`时,没有正确实现其所有纯虚函数(抽象方法)。以下是解决步骤: #### 1. **确认抽象方法签名** 首先检查`SecurityCallbacks`的定义(通常在`esp_ble_sec.h`中),确认所有纯虚函数的签名。典型方法包括: ```cpp virtual void onPasskeyRequest(...) = 0; virtual void onAuthenticationComplete(...) = 0; virtual void onKeyExchange(...) = 0; ``` #### 2. **完整实现派生** 创建派生时**必须实现所有纯虚函数**。示例: ```cpp class MySecurityCallbacks : public SecurityCallbacks { public: // 必须实现所有抽象方法 void onPasskeyRequest(esp_ble_sec_req_t param) override { ESP_LOGI("BLE", "Passkey request received"); // 生成或显示密码 } void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl) override { ESP_LOGI("BLE", "Auth status: %s", cmpl.success ? "OK" : "Fail"); } void onKeyExchange(uint32_t passkey) override { ESP_LOGI("BLE", "Key exchange: %d", passkey); } }; ``` #### 3. **正确初始化BLE安全模块** 在初始化流程中添加安全回调(参考引用[2]的初始化逻辑): ```cpp // 初始化BLE控制器后 esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_init(&bt_cfg); esp_bt_controller_enable(ESP_BT_MODE_BLE); // 设置安全回调 MySecurityCallbacks* secCallbacks = new MySecurityCallbacks(); BLEDevice::setSecurityCallbacks(secCallbacks); // 设置安全参数 esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND; esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT; esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t)); ``` #### 4. **关键注意事项** - **函数签名匹配**:确保派生方法的参数返回型与基**完全一致** - **内存管理**:若使用`new`创建实例,需在适当位置释放内存 - **启用安全特性**:在`menuconfig`中确认已启用`CONFIG_BT_BLE_ENABLED``CONFIG_BT_BLE_42_FEATURES` #### 5. **调试建议** 若仍报错,使用以下命令检查未实现的方法: ```bash # 查看链接错误详情 idf.py build | grep "undefined reference to" ``` > **根本原因**:该错误本质是C++抽象类的实例化规则导致 - 任何包含未实现纯虚函数(`=0`)的都不能直接实例化[^1]。在BLE安全机制中,`SecurityCallbacks`要求开发者实现完整的安全事件处理逻辑[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值