您的位置:首页 > 其它

遍历set容器时,不能修改容器元素的状态

2011-10-08 17:45 225 查看
//  complex_number.h

#pragma once

class ComplexNumber

{

public:

    ComplexNumber(double real, double virt);

    bool operator < (const ComplexNumber& other) const;

    double real() const;

    double virt() const;

    void print();

private:

    double m_real;

    double m_virt;

    int m_count;

};

 

///////////////////////////////////////////////////////////////////////////////////////////////////////

//  complex_number.cpp

#include "complex_number.h"

#include <iostream>

using namespace std;

ComplexNumber::ComplexNumber(double real, double virt)

: m_real(real)

, m_virt(virt)

, m_count(0)

{

    // do nothing

}

double ComplexNumber::real() const

{

    return m_real;

}

double ComplexNumber::virt() const

{

    return m_virt;

}

bool ComplexNumber::operator <(const ComplexNumber &other) const

{

    if (m_real < other.real())

    {

        return true;

    }

    else if (m_virt < other.virt())

    {

        return true;

    }

    return false;

}

void ComplexNumber::print()

{

    cout << "(real,virt): (" << this->m_real << "," << this->m_virt << ")" << endl;

    ++ this->m_count;

}

 

//////////////////////////////////////////////////////////////////////////////////////////////////

// main.cpp

#include "complex_number.h"

#include <set>

#include <iostream>

using namespace std;

int main()

{

    set<ComplexNumber> complex_set;

   

    complex_set.insert(ComplexNumber(1,1));

    complex_set.insert(ComplexNumber(2,3));

    set<ComplexNumber>::iterator iter = complex_set.begin();

    for (; iter != complex_set.end(); ++ iter)

    {

        iter->print();

    }

    return 0;

}

 

1. 在visual studio环境下,编译顺利通过,但在g++环境下,编译报错:

 [root@localhost test]# make

g++   -I . -I ../global -I ../ -g  -c -o complex_number.o complex_number.cpp

g++   -I . -I ../global -I ../ -g  -c -o main.o main.cpp

main.cpp: In function 'int main()':

main.cpp:20: error: passing 'const ComplexNumber' as 'this' argument of 'void ComplexNumber::print()' discards qualifiers

 

2. 原因在于set容器是靠容器元素的operator<来进行遍历的。如果在遍历的时候有操作改变里元素内部状态,可能会引起set容器元素顺序发生变化,因此g++编译报错。即使改变的成员不影响operator<,g++编译器也无法得知(而vc编译器在这点上做得比较好)。

 

3. 因此set容器遍历的时候,一定不要用迭代器去使用能改变容器元素状态的操作,而要用声明为const的操作,可用const_iterator来遍历保证。

 

修改后的代码如下,可正常编译通过。

//  complex_number.h

#pragma once

class ComplexNumber

{

public:

    ComplexNumber(double real, double virt);

    bool operator < (const ComplexNumber& other) const;

    double real() const;

    double virt() const;

    void print() const;

private:

    double m_real;

    double m_virt;

  // int m_count;

};

///////////////////////////////////////////////////////////////////////////////////////////////////////

//  complex_number.cpp

#include "complex_number.h"

#include <iostream>

using namespace std;

ComplexNumber::ComplexNumber(double real, double virt)

: m_real(real)

, m_virt(virt)

, m_count(0)

{

    // do nothing

}

double ComplexNumber::real() const

{

    return m_real;

}

double ComplexNumber::virt() const

{

    return m_virt;

}

bool ComplexNumber::operator <(const ComplexNumber &other) const

{

    if (m_real < other.real())

    {

        return true;

    }

    else if (m_virt < other.virt())

    {

        return true;

    }

    return false;

}

void ComplexNumber::print() const

{

    cout << "(real,virt): (" << this->m_real << "," << this->m_virt << ")" << endl;

   // ++ this->m_count;

}


 

//////////////////////////////////////////////////////////////////////////////////////////////////

// main.cpp

#include "complex_number.h"

#include <set>

#include <iostream>

using namespace std;

int main()

{

    set<ComplexNumber> complex_set;

   

    complex_set.insert(ComplexNumber(1,1));

    complex_set.insert(ComplexNumber(2,3));

    set<ComplexNumber>::const_iterator iter = complex_set.begin();

    for (; iter != complex_set.end(); ++ iter)

    {

        iter->print();

    }

    return 0;

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐