指向对象的指针出现混淆
Confusion in Pointer to the object
在下面的代码中,我定义了int类型的map和类a的对象。我定义了两个函数,funwithPointer和funwithoutPointer。如您所见,我试图在类的对象中增加投票,并将其添加到map中。如果我使用对象的指针,那么在调用第三次时,我得到2的投票,而在声明没有指针的对象(funwithoutPointer)时,我不能增加投票超过1,无论我调用该函数多少次。有什么问题吗?
#include<iostream>
#include<map>
using namespace std;
class A{
public:
int x;int vote;
A(int a):x(a),vote(0){}
void change(){
cout<<vote<<endl;
vote++;}
};
void funwithPointer(map<int,A>& m){
for(int i=0;i<5;i++){
if(m.find(i)==m.end()){
A* a=new A(10);
a->change();
m.insert(pair<int,A>(i,*a));
}
else{
A* a=&m.find(i)->second;
a->change();
}
}
}
void funwithoutPointer(map<int,A>& m){
for(int i=0;i<5;i++){
if(m.find(i)==m.end()){
A a= A(10);
a.change();
m.insert(pair<int,A>(i,a));
}
else{
A a=m.find(i)->second;
a.change();
}
}
}
int main(){
map<int,A> m;
funwithoutPointer(m);
funwithoutPointer(m);
funwithoutPointer(m);
}
In function
void funwithoutPointer(map<int,A>& m){
for(int i=0;i<5;i++){
if(m.find(i)==m.end()){
A a= A(10);
a.change();
m.insert(pair<int,A>(i,a));
}
else{
A a=m.find(i)->second;
a.change();
}
}
}
在声明中 A a=m.find(i)->second;
a.change();
创建a类型的新对象并增加其数据成员。它与映射中的对应对象没有任何共同之处。按如下方式修改这些语句
A &a = m.find(i)->second;
a.change();
,即使用对映射对象的引用。或者您可以这样写
来代替这两个语句 m.find(i)->second.change();
如你所见,在这两个语句之间
A &a = m.find(i)->second;
a.change();
和第一个函数
中的语句 A* a=&m.find(i)->second;
a->change();
有很多共性。要么使用对对象的引用来更改它,要么使用指向该对象的指针
问题在这一行:
A a=m.find(i)->second;
您正在创建映射中对象的副本,命名为a
,然后试图修改该副本。简单的解决方案是使用reference:
A &a=m.find(i)->second;
注意你的代码是相当无效的,更快(和更简单的解决方案)可以是:
auto f = map.find( i );
if( f == map.end() )
f = m.insert( std::make_pair( i, A(10) ) ).first;
f->second.change();
这完全消除了对std::map::find()
的不必要的额外调用,这是非常昂贵的。
另一个更有效的解决方案(感谢Chris Jester-Young):
auto f = map.lower_bound( i );
if( f == map.end() || f->first != i )
f = m.insert( f, std::make_pair( i, A(10) ) );
f->second.change();
你想要的是:
void funwithoutPointer(map<int,A>& m){
for(int i=0;i<5;i++){
map<int,A>::iterator iFind = m.find(i);
if(iFind==m.end()){
A a(10);
a.change();
m[i] = a;
}
else{
iFind->second.change();
}
}
}
如果没有找到,将向映射中插入一个新对象;如果找到了,则允许修改映射中的实际对象
相关文章:
- 为什么指针对象没有调用默认构造函数
- 如何访问双指针对象中的方法
- 如何使用智能指针对象执行成员函数指针
- 调用带有指针对象错误的指针变量
- 如何从模板类重载创建的指针对象上的运算符?
- C++指针对象的运算符重载
- 如何初始化数组指针对象
- 如何打印出唯一指针对象向量中的值(基于范围的循环)?C++
- C++指针对象差异
- 涉及继承,指针对象的交易以及何时进行的问题
- 表达式必须在C 中具有指针对象类型
- 下标需要数组或指针类型表达式必须具有指针对象类型
- 字符指针对象和相应的字符数组元素比较
- 如何在 c++ 中克隆为弱指针对象
- 指针对象使用CPP中的指针表达式进行比较
- Visual Studio中智能指针对象的自定义视图
- 使用指针 /对象 /模板参数正确构成
- 如果我确定只有一个线程一次处理指针/对象,则C/C 仍应使用同步
- 如何将值分配给指针对象 c++
- 更改智能指针对象,然后访问它