【问题标题】:Map UnicodeString as key to Class as value C++Builder将 UnicodeString 作为键映射到类作为值 C++Builder
【发布时间】:2016-08-24 09:43:02
【问题描述】:

我正在使用 C++Builder XE7。我想使用带有 UnicodeString 作为键和类作为值的映射。

这是我的课:Historique.h

#ifndef HistoriqueH
#define HistoriqueH
#include <System.Classes.hpp>
#include <string>    

class MyHistorique
{
    public:
        __fastcall MyHistorique();
        __fastcall MyHistorique(const MyHistorique& mh);

        //Getters
        String __fastcall getNumClient(){return numClient;}
        bool __fastcall getTypeAppel(){return typeAppel;}
        String __fastcall getCodeClient(){return codeClient;}
        String __fastcall getDate(){return date;}
        String __fastcall getHeure(){return heure;}
        String __fastcall getNumCti(){return numCti;}
        bool __fastcall getAppelRecuManque(){return appelRecuManque;}
        String __fastcall getDebutConvers(){return debutConvers;}
        String __fastcall getFinConvers(){return finConvers;}
        String __fastcall getDureeConvers(){return dureeConvers;}
        bool __fastcall getFlag(){return flag;}

        //Setters
        void __fastcall setNumClient(String nc){numClient = nc;}
        void __fastcall setTypeAppel(bool ta){typeAppel = ta;}
        void __fastcall setCodeClient(String cc){codeClient = cc;}
        void __fastcall setDate(String d){date = d;}
        void __fastcall setHeure(String h){heure = h;}
        void __fastcall setNumCti(String nCti){numCti = nCti;}
        void __fastcall setAppelRecuManque(bool arm){appelRecuManque = arm;}
        void __fastcall setDebutConvers(String dc){debutConvers = dc;}
        void __fastcall setFinConvers(String fc){finConvers = fc;}
        void __fastcall setDureeConvers(String dureeC){dureeConvers = dureeC;}
        void __fastcall setFlag(bool f){flag = f;}

    private:
        String numClient;
        bool typeAppel;
        String codeClient;
        String date;
        String heure;
        String numCti;
        bool appelRecuManque;
        String debutConvers;
        String finConvers;
        String dureeConvers;
        bool flag;
};

在我的 Application.h 中:

#include <map>
#include "Historique.h"

class TForm1 : public TForm
{
    public:
    std::map<UnicodeString, MyHistorique> myMap;
};

在我的 Application.cpp 中:

void __fastcall TForm1::XPhonePc1EvtIdCall(TObject *Sender, long nIdCall)
{
    ShowMessage(nIdCall);
    myMap[nIdCall] = new MyHistorique();  
}

我想要的是创建一个空对象并用nIdCall 分配它,但我有这个错误:

[bcc32 Erreur] ApplicationPhonePC.cpp(496): E2285 Impossible de trouver une 对应倒'operator MyHistorique::=(MyHistorique *)'
上下文分析完成
ApplicationPhonePC.cpp(493): 分析: void _fastcall TForm1::XPhonePc1EvtIdCall(TObject *,long)

【问题讨论】:

  • 当您明确使用long 值时,为什么要使用UnicodeString 作为键?

标签: c++ dictionary std c++builder stdmap


【解决方案1】:

错误消息告诉您编译器找不到可以将MyHistorique* 指针分配给MyHistorique 对象实例的operator= 定义。这是正确的,因为你没有定义一个(你也不应该)。

您的std::map 包含实际的MyHistorique 对象实例,而不是指向对象的指针,因此您需要删除对new 的调用,以便编译器可以调用MyHistorique 的复制赋值运算符:

MyHistorique tmp;
myMap[nIdCall] = tmp;

或者简单地说:

myMap[nIdCall] = MyHistorique();

或者,我建议向MyHistorique 添加一个方法以将其当前字段重置为默认值:

class MyHistorique
{
public:
    void Reset();
};

void MyHistorique::Reset()
{
    numClient = ...;
    typeAppel = ...;
    codeClient = ...;
    ... and so on ...
}

然后像这样调用那个方法:

myMap[nIdCall].Reset();

但是请注意,如果nIdCall 尚不存在于std::map 中,这将是多余的。新插入nIdCall时,其关联对象会在std::map::operator[]返回之前默认构造,所以你不需要调用Reset()。您可以使用std::map::find() 绕过该冗余操作:

std::map<UnicodeString, MyHistorique>::iterator iter = myMap.find(nIdCall);
if (iter != myMap.end())
    iter->second.Reset();
else
    myMap.insert(std::make_pair(nIdCall, MyHistorique()));

另一方面,如果您知道nIdCall 将始终是一个新值并且永远不会预先存在于std::map 中,您可以忽略以上所有内容并改为执行此操作:

void __fastcall TForm1::XPhonePc1EvtIdCall(TObject *Sender, long nIdCall)
{
    ShowMessage(nIdCall);
    myMap[nIdCall];  
}

【讨论】:

  • 是正确的。我只是想补充一点,您可以使用 boost 的 ptr_map,它可以接受指针并自动进行清理。
  • 哦,我更好理解并且它有效。我已经用了几天了。非常感谢雷米。并感谢大家。祝你有美好的一天!
【解决方案2】:

试试 myMap[nIdCall] = new MyHistorique();

完成后不要忘记从地图中删除实例

【讨论】:

  • 抱歉,我忘记更改了。这是现在的实际错误。 [ilink32 Erreur] 错误:'__fastcall MyHistorique::MyHistorique()' externe non résolu, référencé depuis C:\USERS\SRAADM\DOCUMENTS\EMBARCADERO\STUDIO\PROJETS\WIN32\DEBUG\APPLICATIONPHONEPC.OBJ [ilink32 Erreur] 错误:' __fastcall MyHistorique::MyHistorique(MyHistorique&)' externe non résolu, référencé depuis C:\USERS\SRAADM\DOCUMENTS\EMBARCADERO\STUDIO\PROJETS\WIN32\DEBUG\APPLICATIONPHONEPC.OBJ [ilink32 Erreur] Error: Impossible d'effectuer le lien
  • 好的,谢谢。我试过这个,我有这个:[bcc32 Erreur] ApplicationPhonePC.cpp(496): E2285 Impossible de trouver une 对应倒'operator MyHistorique::=(MyHistorique *)' Contexte d'analyseur complet ApplicationPhonePC.cpp(493 ): 分析: void _fastcall TForm1::XPhonePc1EvtIdCall(TObject *,long)
  • 不懂法语...但是将地图更改为存储 MyHistorique 类型的指针,即 std::map
  • 请不要更改地图来存储指针!这只会给程序员增加手动管理内存分配的负担。至少如果您使用 C++11(Win64 或移动编译器),您可以在 map 中使用 std::unique_ptr&lt;MyHistorique&gt; 而不是 MyHistorique*。但在早期的 C++ 版本(Win32 编译器)中,这不是一个选项。在这种情况下也没有必要。请参阅我的答案以获得不同的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-12
  • 1970-01-01
相关资源
最近更新 更多