使用迭代器处理vector对象

using iterator with a vector of objects c++

本文关键字:vector 对象 处理 迭代器      更新时间:2023-10-16

我有一个包含ofstream文件的类,在使用迭代器删除时遇到问题该类对象的向量的对象

错误如下:

Error 10 error C2249: 'std::basic_ios<_Elem,_Traits>::operator =' : no accessible path to private member declared in virtual base 'std::basic_ios<_Elem,_Traits>' c:program files (x86)microsoft visual studio 10.0vcincludeostream

代码:

static vector<VOIP> calls;
...
for(...)
{
    VOIP v = VOIP(...);
    calls.push_back(v);
}
...
for( int i = 0 ; i < calls.size() ; i++)
{
    if(...)
    {
        vector<VOIP>::iterator it = calls.begin() + i;
        calls.erase(it);//"?"
        break;
    }
}

Face Error C2249 raise from line "?",有帮助吗这是类

class VOIP
{
public:
    VOIP(string SourceDirectoryPath, string startTime, signalling sig, int callerIp[], int calleeIp[], int callerPort, int calleePort);
    VOIP(const VOIP & voip);
    ~VOIP(void);
    //caller and callee voice vectors 
    vector<u_char> callerVoiceVector;
    vector<u_char> calleeVoiceVector;
    //caller and callee voice files and path
    ofstream callerVoiceFile;
    ofstream calleeVoiceFile;   
    string outFilePath;
    string log;
    ofstream logFile;
    string startTime;
    string endTime;
    string length;
}
在复制构造函数中

注释行引发相同的错误,即错误C2249

VOIP::VOIP(const VOIP & voip)
    /*:calleePort(voip.calleePort), calleeVoiceFile(voip.calleeVoiceFile), calleeVoiceVector(voip.calleeVoiceVector),
     callerPort(voip.callerPort), callerVoiceFile(voip.callerVoiceFile), callerVoiceVector(voip.callerVoiceVector),
     callType(voip.callType), endTime(voip.endTime), length(voip.length), log(voip.log), logFile(voip.logFile),
     outFilePath(voip.outFilePath), startTime(voip.startTime),
     pleaseDial(voip.pleaseDial), DLHmm(voip.DLHmm)//signalings*///TODO
{
    cout<<"inside copy constractor"<<endl;
}
VOIP::~VOIP(void)
{
    callerVoiceVector.clear();
    calleeVoiceVector.clear();
    callerVoiceFile.close();
    calleeVoiceFile.close();
    logFile.close();
    cout<<"inside destractor"<<endl;
}

标准库容器通常要求它们所包含的对象可以是可复制构造的,也可以是可复制赋值的。也就是说,它们需要访问复制构造函数(在您的示例中是VOIP::VOIP(const VOIP&))和复制赋值操作符(在您的示例中是VOIP::operator=(const VOIP&))。如果你的类没有显式地提供这些函数,这些函数将由编译器自动生成,只要它能做到这一点:也就是说,只要所有的类成员也是可复制构造的或可复制赋值的,VOIP就不是这样,因为ofstream不能被复制。

然而,VOIP提供了一个显式的复制构造函数,所以没有问题。这就是为什么需要复制构造函数的vector<VOIP>::push_back()可以工作的原因。不幸的是,它没有提供复制赋值操作符,而且看起来很奇怪,vector<VOIP>::erase()需要它。原因是,当从vector中擦除一个元素时,必须将该元素之后的所有元素复制到前一个位置,以填补空白。这就是错误信息告诉你的:ofstream是不可复制的,因为它的基类std::basic_ios<>是不可复制的,所以VOIP是不可复制的。

要解决这个问题,可以按照复制构造函数的思路,为VOIP提供一个复制赋值操作符。顺便说一句,在c++中有一种叫做规则:如果一个类有显式析构函数、复制构造函数或复制赋值操作符,它通常需要所有这三个。VOIP有前两个,但是没有第三个。写下来,一切都会好的。