从C ++函数返回整个自定义类型数组

时间:2015-11-18 15:28:17

标签: c++ refactoring mbed

我正在开发一个c ++应用程序,用一些信息填充蓝牙阵列。它基于mbed平台BLE_API,但我不认为这应该是相关的。我有以下代码,我试图重新考虑到一个函数。

GattAttribute nameDescr1(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Percentage", strlen("Percentage"));
GattAttribute *pdescriptors[] = { &nameDescr1 };


  PercentageFill(PercentageUUID, valueBytes.getPointer(),
                   valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
                   GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
                   pdescriptors,
                   sizeof(pdescriptors) / sizeof(GattAttribute*)),

我到目前为止得到了这个:

   GattAttribute produceName (char title[]) { 
        GattAttribute nameDescr(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)title, strlen(title));
        GattAttribute *descriptors[] = { &nameDescr };
        return descriptors;
    }

然而,可以预见我会抛出一个错误:

  

错误:没有合适的构造函数可以从“GattAttribute * [1]”转换为“GattAttribute”

我可以看出为什么它会抛出这个,但我不确定我应该如何返回整个数组,因为这是“PercentageFill”构造函数所需的格式。

感谢。

更新

为了给出完整的上下文,这里是我正在设置的另一个Characteristcis(每个都有不同的名称):

NewService(BLE &_ble, uint8_t percentageFill, uint8_t replacementDue) :
    ble(_ble),
    valueBytes(percentageFill),
    PercentageFill(PercentageUUID, valueBytes.getPointer(),
                   valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
                   GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
                   pdescriptors,
                   sizeof(pdescriptors) / sizeof(GattAttribute*)),
    Time(   TimeUUID,
            &replacementDue,
            GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
            tdescriptors,
            sizeof(tdescriptors) / sizeof(GattAttribute*)),
    UseProfile( UseProfileUUID, 
                &controlPointValue,
                GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
                Udescriptors,
                sizeof(Udescriptors) / sizeof(GattAttribute*)),) {
                setupService();
}

2 个答案:

答案 0 :(得分:2)

函数produceName声明返回GattAttribute对象,但是您尝试返回指向GattAttribute个对象的指针数组。相当不同。

但这并不是你代码中最糟糕的部分。如果你修复了声明返回类型以便代码构建,那么你会遇到一个更糟糕的问题,导致未定义的行为:你返回指向局部变量的指针。一旦函数返回,那些局部变量将不复存在,并且不能使用任何指向它们的指针。

答案 1 :(得分:1)

首先:请注意原始代码中的pdescriptors数组只有一个元素。因此,指向对象的直指针可以正常工作,或者如果百分比填充没有预期指针数组。我们可以通过传递指针指针和大小为1来模仿这一点。请注意:原始代码中的sizeof(...)/sizeof(...)计算也意味着返回1,当您引入函数边界时这会变得棘手(特别是当将数组作为参数传递给函数。)

除此之外,你的问题有点不清楚:你是否打算让不同的GattAttribute值成为可能?如果没有,你可能会做类似的事情:

void updatePercentage(WhateverTypeValueBytesIs valueBytes) {
    GattAttribute nameDescr(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Percentage", strlen("Percentage"));
    GattAttribute * ptr = &nameDescr; // needed, because we want to pass pointer-to-pointer-to-nameDescr
    PercentageFill(PercentageUUID, valueBytes.getPointer(),
               valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
               GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
               &ptr, 1), /* are we sure about trailing comma here? */
    // other relevant trailing code?
}

根据您在评论中提到的无法访问的复制构造函数的错误消息判断,GattAttribute可能是一个常规构造函数,因此不需要在那里创建其他函数。如果你想将这个特定的GattAttribute变成某些东西,你可以隐藏在功能界面后面,然后查找'如果需要,那么你可以将它变成这样的单身(例如,存在实现相同目标的其他方式):

GattAttribute * getNameDescriptor(void) {
    static GattAttribute nameDescr(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Percentage", strlen("Percentage"));
    return &nameDescr;
}

然后您可以使用这样的功能:

void updatePercentage(WhateverTypeValueBytesIs valueBytes) {
    GattAttribute * ptr = getNameDescriptor(); // needed, because we want to pass pointer-to-pointer-to-nameDescr
    PercentageFill(PercentageUUID, valueBytes.getPointer(),
               valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
               GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
               &ptr, 1), /* are we sure about trailing comma here? */
    // other relevant trailing code?
}

编辑以根据评论添加其他选项:

void updatePercentage(WhateverTypeValueBytesIs valueBytes, const char* name) {
    GattAttribute nameDescr(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (const uint8_t *) name, strlen(name));
    GattAttribute * ptr = &nameDescr; // needed, because we want to pass pointer-to-pointer-to-nameDescr
    PercentageFill(PercentageUUID, valueBytes.getPointer(),
               valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
               GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
               &ptr, 1), /* are we sure about trailing comma here? */
    // other relevant trailing code?
}

或另一种选择:琐碎,通过引用传递完全初始化的GattAttribute

void updatePercentage(WhateverTypeValueBytesIs valueBytes, GattAttribute & descr) {
    GattAttribute * ptr = &descr; // needed, because we want to pass pointer-to-pointer-to-descr
    PercentageFill(PercentageUUID, valueBytes.getPointer(),
               valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
               GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
               &ptr, 1), /* are we sure about trailing comma here? */
    // other relevant trailing code?
}

您可以这样称呼:

void foo(WhateverTypeValueBytesIs valueBytes) {
    GattAttribute nameDescr(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Percentage", strlen("Percentage"));
    updatePercentage(valueBytes, nameDescr);
}

显然,除了使用引用之外,您还可以重做函数以获取指向GattAttribute对象的指针(并使用ptr变量代替ptr变量,与valueBytes变量相同在例子中使用。

进一步补充:请注意,您可能希望在将updatePercentage传递给private List<ICommandItem> _items; private void ProcessCommands() { while(_items.count > 0) { _items[0].Execute(); _items.RemoveAt(0); } } 时避免复制/** * @var string */ protected $roles; ,此处您可能希望通过引用传递它。