`
yzd
  • 浏览: 1818765 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

从一道题谈C++容器内元素的类型约束

 
阅读更多

《C++ primer》第四版中文267页,9.1.2

  • 元素类型必须支持赋值运算。
  • 元素类型的对象必须可以复制。

不久前我复习的时候还标记了一下,没想到理解得还不深刻啊。。

今天算法群有网友提问

这个程序看起来很蛋疼啊, x,y还搞成const...好吧,姑且不说这个了,说一下程序的问题。

这个程序直接编译的话,会有错误

但是加了个赋值函数,里面是空的,就通过编译了

Point& operator= (const Point& p)
{

std::cout << " ok" << std::endl;

}
这个cout语句被没有执行

首先,回到开头我提到的《C++ primer》里面所说的约束条件,放入vector的类一定要支持赋值和复制操作! 但对于一般自己定义的类,我们如果不定义的话,使用系统默认提供的复制和赋值函数就行了,不会有什么问题。但这道题由于使用了const成员变量,又有了其他问题。

“对包含const成员变量的类而言,编译器不提供默认 赋值拷贝 ( = ) 函数的需要自己定义”

http://blog.csdn.net/cleverwyq/archive/2007/06/23/1663809.aspx

这就解释了为什么我们不定义赋值函数,编译器会报错!

但在赋值函数里面加了cout打印信息,为什么又没有输出呢?
vector.tcc里面的代码不是一般的不好懂, 我还没看STL的源码剖析,所以不敢乱吹。暂时的话,也没有什么兴趣研究(还有另外一个问题,STL怎么实现提供默认的复制赋值函数?)。姑且认为vector会检查复制和赋值函数两个条件吧(注意到出错的提示是在push_back函数。直觉上像是因为调用引起错误的...),因为实际上的的确确没有打印出东西,我们可以肯定程序没有执行进去。我们显式调用赋值函数后,即

程序确实有输出。



最后的结论:”对包含const成员变量的类而言,一定记得自己定义赋值函数哦亲”

这道题我之前没能想出来,实在惭愧。我自己平时玩acm,所以还是写c比较多,c++当然也有学。不过,学校的课不要指望能有多深,水得不行。我自己觉得把,编程的话还是得自己多写,在实践中学习那是最好的。类比一个例子,就像背单词一样,拿着单词本背我觉得很不好,很多时候即使看到那个单词,你依然不能断定到底这里面是用了单词的哪个解释;又或者想用一个词的时候,想不起那个词来。一些人原本英语很烂,但出国多年后英语照样杠杠的,我觉得在实际的语境中学语言是最好的,编程也一样!

在群友的追问下,得知这道题的来源..

这个题目是金山的笔试题
编译下面的代码(左侧的数字是行号,并非代码的一部分,文件名为hello.cpp)
1#include<vector>
2
3structPoint{
4Point(intxx,intyy)
5:x(xx)
6,y(yy)
7{}
8
9intconstx;
10intconsty;
11};
12
13intmain()
14{
15std::vector<Point>pts;
16pts.push_back(Point(0,0));
17return0;
18}
会产生类似下面的编译错误
hello.cpp:Inmemberfunction‘Point&Point::operator=(constPoint&)’:
hello.cpp:3:14:
instantiatedfrom`
voidstd::vector<_Tp,_Alloc>::insert(std::vector<_Tp,_Alloc>::iterator,
const_Tp&)
[with
_Tp=Point,
_Alloc=std::allocator<Point>
]'

/usr/include/.../stl_vector.h:??:??:
instantiatedfrom`voidstd::vector<_Tp,_Alloc>::push_back(constvalue_type&)
[with
_Tp=Point,
_Alloc=std::allocator<Point>,
value_type=Point
]'

hello.cpp:16:30:instantiatedfromhere
hello.cpp:3:14:error:non-staticconstmember`constintPoint::x',
can'tusedefaultassignmentoperator
hello.cpp:3:14:error:non-staticconstmember`constintPoint::y',
can'tusedefaultassignmentoperator

Infileincludedfrom/usr/include/...ector:??:??,
fromhello.cpp:1:
/usr/include/...ector.tcc:Inmemberfunction`
voidstd::vector<_Tp,_Alloc>::insert(std::vector<_Tp,_Alloc>::iterator,
const_Tp&)
[with
_Tp=Point,
_Alloc=std::allocator<Point>
]':
/usr/include/...ector.tcc:??:??:note:synthesizedmethod
`Point&Point::operator=(constPoint&)'firstrequiredhere
请问,编译错误要表达什么信息?你会如何修改上述代码以编译通过,同时保持相近的代码意义?

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics