我的特定应用程序的memcpy或std :: copy

时间:2015-05-13 20:44:02

标签: c++ algorithm memcpy

我正在尝试为某些遗留 select CASE WHEN to_char(A.DATA_POSICAO_CARTEIRA, 'YYYYMMDD') <= '20110513' THEN A.CODIGO_FAVORECIDO ELSE A.CODIGO_FAVORECIDO_ORIGINAL END AS CODIGO_FAVORECIDO, '13/05/11' AS POSICAO_CARTEIRA, B.BANCO, B.AGENCIA, B.CONTA, sum(nvl(CASE WHEN TV.VALOR_PARCELA = 0 THEN TV.VALOR_VENDA ELSE TV.VALOR_PARCELA END, 0)) + sum(nvl(CASE WHEN TAV.VALOR_PARCELA = 0 THEN TAV.VALOR_ANULACAO ELSE TAV.VALOR_PARCELA END, 0)) as VALOR_BRUTO, sum(nvl(CASE WHEN TV.VALOR_PARCELA = 0 THEN TV.VALOR_DESCONTO ELSE TV.VALOR_PARCELA_DESCONTO END, 0)) + sum(nvl(CASE WHEN TAV.VALOR_PARCELA = 0 THEN TAV.VALOR_DESCONTO ELSE TAV.VALOR_PARCELA_DESCONTO END, 0)) as VALOR_COMISSAO, sum(nvl(CASE WHEN TV.VALOR_PARCELA = 0 THEN TV.VALOR_VENDA ELSE TV.VALOR_PARCELA END, 0)) + sum(nvl(CASE WHEN TAV.VALOR_PARCELA = 0 THEN TAV.VALOR_ANULACAO ELSE TAV.VALOR_PARCELA END, 0)) + sum(nvl(CASE WHEN TV.VALOR_PARCELA = 0 THEN TV.VALOR_DESCONTO ELSE TV.VALOR_PARCELA_DESCONTO END, 0)) + sum(nvl(CASE WHEN TAV.VALOR_PARCELA = 0 THEN TAV.VALOR_DESCONTO ELSE TAV.VALOR_PARCELA_DESCONTO END, 0)) as VALOR_LIQUIDO, D.NOME_PRODUTO AS DESCRICAO_PRODUTO, E.CNPJ_FAVORECIDO AS CNPJ, E.NOME_FAVORECIDO, G.CODIGO_EMPRESA_GRUPO, trunc(A.DATA_REPASSE_CALCULADA) as DATA_REPASSE_CALCULADA, G.DESCRICAO_EMPRESA_GRUPO from TB_TRANSACAO A left join TB_CONTA_FAVORECIDO B on B.CODIGO_CONTA_FAVORECIDO = CASE WHEN to_char(A.DATA_POSICAO_CARTEIRA, 'YYYYMMDD') <= '20110513' THEN A.CODIGO_CONTA_FAVORECIDO ELSE A.CODIGO_CONTA_FAVORECIDO_ORIG END left join TB_TRANSACAO_VENDA TV on A.CODIGO_TRANSACAO = TV.CODIGO_TRANSACAO left join TB_TRANSACAO_ANULACAO_VENDA TAV on A.CODIGO_TRANSACAO = TAV.CODIGO_TRANSACAO left join TB_ESTABELECIMENTO C on A.CODIGO_ESTABELECIMENTO = C.CODIGO_ESTABELECIMENTO left join TB_PRODUTO D on A.CODIGO_PRODUTO = D.CODIGO_PRODUTO left join TB_FAVORECIDO E on E.CODIGO_FAVORECIDO = CASE WHEN to_char(A.DATA_POSICAO_CARTEIRA, 'YYYYMMDD') <= '20110513' THEN A.CODIGO_FAVORECIDO ELSE A.CODIGO_FAVORECIDO_ORIGINAL END left join TB_EMPRESA_SUBGRUPO F on C.CODIGO_EMPRESA_SUBGRUPO = F.CODIGO_EMPRESA_SUBGRUPO left join TB_EMPRESA_GRUPO G on F.CODIGO_EMPRESA_GRUPO = G.CODIGO_EMPRESA_GRUPO WHERE A.TIPO_TRANSACAO IN ('CV', 'AV') and A.STATUS_TRANSACAO <> 6 group by CASE WHEN to_char(A.DATA_POSICAO_CARTEIRA, 'YYYYMMDD') <= '20110513' THEN A.CODIGO_FAVORECIDO ELSE A.CODIGO_FAVORECIDO_ORIGINAL END, '13/05/11', B.BANCO, B.AGENCIA, B.CONTA, D.NOME_PRODUTO, E.CNPJ_FAVORECIDO, E.NOME_FAVORECIDO, G.CODIGO_EMPRESA_GRUPO, A.DATA_REPASSE_CALCULADA, G.DESCRICAO_EMPRESA_GRUPO ORDER BY E.CNPJ_FAVORECIDO, E.NOME_FAVORECIDO, B.CONTA, B.AGENCIA, B.BANCO 代码编写C++包装,以提高其类型安全性并使其不再使用PITA。遗留代码与共享内存中的指针交互。 POD结构是从这些指针转换而来的。由于它是共享内存,因此这些结构保证是POD。

C代码中充斥着C个实例。我想知道在这种情况下使用memcpy而不是std::copy是否是个好主意,或者最好不要理会它。

例如,原始代码(以伪代码表示):

memcpy

其中// we cast from a void pointer return from the shared memory segment void *ptr = FunctionToReturnPointer(); descriptor_p = (descriptor_t*)new char[sizeof(descriptor_t)]; memcpy(descriptor_p, ptr, sizeof(descriptor_t)); 是POD结构。在我的解决方案中,我可能会做这样的事情(用伪代码表示):

descriptor_t

所以这是我的问题:

  1. 这样做有益吗?或者这是一个傻瓜的差事?
  2. 我是否在代码中添加了任何类型安全性?
  3. 我对// provide a casting class that can do everything template <typename T> class CastClass { static T* Cast() { void *ptr = FunctionToReturnPointer(); T *t = new T; std::copy(ptr, ptr + sizeof(T), t); return t; } }; // And how I would use the function descriptor_p = CastClass<descriptor_t>::Cast(); 算法的使用是否正确?

3 个答案:

答案 0 :(得分:2)

两者怎么样?只需使用正确键入的指针使对象的默认复制分配工作:

ArticleId

一行:

descriptor_t* descriptor_p = new descriptor_t;
*descriptor_p = *(descriptor_t*)(FunctionToReturnPointer());

模板版本:

descriptor_t* descriptor_p = new descriptor_t(*(descriptor_t*)(FunctionToReturnPointer()));

这比现在看起来要干净得多,但是如果你给模板提供了错误的类型,编译器就无法帮助你,所以“安全”是一个相对术语。任何时候你使用虚空*并施放它你就会脱掉手套。尝试尽可能地包含该行为,以便您的代码几乎只处理正确类型的指针。

答案 1 :(得分:1)

你真的需要在堆上动态分配副本吗?

// provide a casting class that can do everything
template <typename T>
class CastClass {
    public:
    static T Cast() {
        T *ptr = (T*) FunctionToReturnPointer();
        return *ptr; // return a copy of the data
    }
};

descriptor_t descriptor_p = CastClass<descriptor_t>::Cast();

如果确实需要指针,那么至少使用unique_ptr进行管理:

// provide a casting class that can do everything
template <typename T>
class CastClass {
    public:
    static std::unique_ptr<T> Cast() {
        T *ptr = (T*) FunctionToReturnPointer();
        return new T(*ptr); // return a managed pointer to a copy of the data
    }
};

std::unique_ptr<descriptor_t> descriptor_p = CastClass<descriptor_t>::Cast();

答案 2 :(得分:0)

std::copy(ptr, ptr + sizeof(T), t);

不对。

首先,我不认为你可以在void*的电话中传递std::copy类型的对象

即使您做了类似的事情:

T* ptr = static_cast<T*>(FunctionToReturnPointer());
...
std::copy(ptr, ptr + sizeof(T), t);

有问题。

T == intsizeof(int)4

std::copy的使用将尝试复制:

*t*ptr
 *(t+1)*(ptr+1)
 *(t+2)*(ptr+2)
 *(t+3)*(ptr+3)

您的代码没有为这些对象分配内存,并且会导致未定义的行为。