// 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;
}