从一道题谈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
 3 struct Point {
 4     Point(int xx, int yy)
 5         : x(xx)
 6         , y(yy)
 7     {}
 8
 9     int const x;
10     int const y;
11 };
12
13 int main()
14 {
15     std::vector<Point> pts;
16     pts.push_back(Point(0, 0));
17     return 0;
18 }
会产生类似下面的编译错误
hello.cpp: In member function ‘Point& Point::operator=(const Point&)’:
hello.cpp:3:14:
instantiated from `
    void std::vector<_Tp, _Alloc>::insert(std::vector<_Tp, _Alloc>::iterator,
                                                 const _Tp&)
[with
    _Tp = Point,
    _Alloc = std::allocator<Point>
]'

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

hello.cpp:16:30:   instantiated from here
hello.cpp:3:14: error: non-static const member `const int Point::x',
                   can't use default assignment operator
hello.cpp:3:14: error: non-static const member `const int Point::y',
                   can't use default assignment operator

In file included from /usr/include/...ector:??:??,
                 from hello.cpp:1:
/usr/include/...ector.tcc: In member function `
    void std::vector<_Tp, _Alloc>::insert(std::vector<_Tp, _Alloc>::iterator,
                                                 const _Tp&)
[with
    _Tp = Point,
    _Alloc = std::allocator<Point>
]':
/usr/include/...ector.tcc:??:??: note: synthesized method
                 `Point& Point::operator=(const Point&)' first required here
请问, 编译错误要表达什么信息? 你会如何修改上述代码以编译通过, 同时保持相近的代码意义?

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值