根据用户输入从模板创建对象

时间:2012-06-18 14:47:58

标签: c++ oop templates pointers cryptography

我正在使用crypto ++库编写应用程序。对于那些不熟悉它的人,ECB_Mode模板类继承自CipherModeBase。程序编译并运行,但我得到的输出是不正确的。当我从cipher_object调用加密方法时,它的工作方式与我直接使用ECB_Mode对象的方式不同。我已经验证了正确分配了选项对象实例变量。我想在if_then_else结构或switch_case中创建实例,这样我就可以保持代码的良好和DRY。我做错了什么?

以下是我正在尝试但不起作用的内容:

    CipherModeBase *cipher_object;
    cipher_object == NULL;

    if(options->cipher == BS_AES)
    {
        ECB_Mode<AES >::Encryption ecbEncryption(options->key, options->keylen);
        cipher_object = &ecbEncryption;
    }
    else if(options->cipher == BS_TWOFISH)
    {
        ECB_Mode<Twofish >::Encryption ecbEncryption(options->key, options->keylen);
        cipher_object = &ecbEncryption;     
    }
cipher_object->processData(args);

以下是有效的方法:

ECB_Mode<AES >::Encryption ecbEncryption(options->key, options->keylen);
ecbEncryption.processData(args);

PS。我知道不要使用ECB模式。我只是不想弄乱IV,直到我能把一切都搞定。我对C ++也缺乏经验。

2 个答案:

答案 0 :(得分:2)

您的ecbEncryption对象在if和else作用域内的堆栈上声明。 (范围是用大括号括起来的东西)。

在退出时声明对象的范围将被销毁。因此,在调用该方法之前,您正在调用processData的对象已被删除。显然这是行不通的。

一个选项是您可以在堆上声明对象而不是堆栈。这样,可以控制生命周期以按照您想要的方式工作。

尝试使用std :: unique_ptr作为cipher_object而不是原始指针。然后,在if和else子句中分配给它:

cipher_object.reset( new ECB_Mode<AES>::Encryption(options->key, options->keylen) );

然后,对象将保留在堆上,直到cipher_object的范围结束,此时unique_ptr将为您删除它。并且,cipher_object的范围将持续到您调用任何方法之后。

答案 1 :(得分:1)

下面:

cipher_object == NULL;

if(options->cipher == BS_AES)
{
    // v
    ECB_Mode<AES >::Encryption ecbEncryption(options->key, options->keylen);
    cipher_object = &ecbEncryption;
}

ecbEncryption是该范围的本地。您正在存储本地的地址,并在超出范围后使用它。这是未定义的行为。您应该使用new关键字在堆上分配它:

if(options->cipher == BS_AES)
{
    cipher_object = new ECB_Mode<AES >::Encryption(options->key, options->keylen);
}

你应该对另一个if语句做同样的事。

另请注意:

cipher_object == NULL;

应改为:

cipher_object = NULL;

但问题应该使用上面的代码来解决。