运算符重载:C++
Operator Overloading: C++
我有一个关于C++中运算符重载的问题。
对于一个赋值,我必须编写一个包含数组的类,有点像Java中的ArrayList。
我要做的一件事就是跟踪数组的大小。Size是包含的元素数量,而capacity是在类必须扩展数组之前可以包含的最大数量。
客户端代码在调用构造函数时指定大小。然而,当添加新元素时,我必须想办法更改大小。
我的老师说了一些关于能够为平等的不同方面重载运算符的内容。这是真的吗,还是我误解了她?如果这有效的话,这将是我的问题的最佳解决方案。
我目前对[]操作员的过载是:
int & ArrayWrapper::operator [] (int position){
if(position == _size){
if(_size == _capacity){
changeCapacity(_capacity+10);
}
}
return _array[position];
}
这对于检索来说很好,但我希望有它,这样如果有人从'='的左手边调用它,它就会检查是否需要扩展大小。
编辑:如果这不是真的,有人能想出不同的解决方案吗?我想到的一个解决方案是每次调用getSize()方法时都只遍历整个数组,但我真的不想使用这个解决方案,因为它看起来很俗气。
编辑:为了澄清,我不是在问我对数组的扩展是否有效。每次添加新元素时,我都需要在大小上加1。例如,如果客户端创建了一个大小为15、容量为25的数组,然后尝试向array[15]添加一些内容,则应该将大小增加到16。我想知道是否有办法在超载的情况下做到这一点。
一个简单的方法是重载数组是const
还是可变的,这并不能完全满足您的需要。
这并不能区分数组是在赋值的左侧使用(作为左值)还是在右侧使用(作为右值 如果你真的想知道你是否被分配到,那么你必须返回一个代理作为引用。这重载了向数组写入的赋值,并提供了一个转换运算符来获取元素的值: 您可能需要将其声明为// Mutable overload (returns a mutable reference)
int & operator[](size_t position) {
if (position >= _size) {
if (position >= _capatity) {
// increase capacity
}
// increase size
}
return _array[position];
}
// Const overload (returns a value or const reference)
int operator[](size_t position) const {
if (position >= _size) {
throw std::out_of_range("Array position out of range");
}
return _array[position];
}
class proxy {
public:
proxy(ArrayWrapper & array, size_t position) :
_array(array), _position(position) {}
operator int() const {
if (_position >= _array._array._size) {
throw std::out_of_range("Array position out of range");
}
return _array._array[_position];
}
proxy & operator=(int value) {
if (_position >= _size) {
if (_position >= _capatity) {
// increase capacity
}
// increase size
}
_array._array[_position] = value;
return *this;
}
private:
ArrayWrapper & _array;
size_t _position;
};
ArrayWrapper
的friend
;然后从operator[]
:返回proxy ArrayWrapper::operator[](size_t position) {
return proxy(*this, position);
}
这种方法很好。不过,代码中有一个错误:如果有人调用的运算符的位置等于数组的当前大小加100,会发生什么?
问题是您是否真的想要根据你在=
的哪一边。你的基本想法会很好,但会无论你在哪一边,都要扩展阵列,例如:
ArrayWrapper a(10);
std::cout << a[20] << std::end;
将导致扩展阵列。在这种情况下,优选的行为是上面的代码引发异常,但对于
ArrayWrapper a(10);
a[20] = 3.14159;
工作。使用代理可以做到这一点:首先,定义double
ArrayWrapper::get( int index ) const
和void ArrayWrapper::set( int
index, double newValue )
;如果索引超出了界限,但是setter将扩展数组。然后operator[]
返回一个代理,行为:
class ArrayWrapper::Proxy
{
ArrayWrapper* myOwner;
int myIndex;
public:
Proxy( ArrayWrapper& owner, int index )
: myOwner( &owner )
, myIndex( index )
{
}
Proxy const& operator=( double newValue ) const
{
myOwner->set( myIndex, newValue );
}
operator double() const
{
return myOwner->get( myIndex );
}
};
如果您不熟悉operator double()
,它是重载转换运算符。其工作方式是,如果operator[]
在分配的左侧,它实际上是被分配到的代理,以及proxy转发到CCD_ 11函数。否则,代理将隐式转换为double
,并且此转换转发到CCD_ 13功能。
- 继承函数的重载解析
- 你能重载对象变量名本身返回的内容吗
- 从父命名空间重载类型
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 重载操作程序时出错>>用于类中的字符串 memebr
- 一个关于在C++中重载布尔运算符的问题
- 不同翻译单元中不可重载的非内联函数定义
- 为什么使用SFINAE而不是函数重载
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 将重载的成员函数传递给函数模板
- c++:可变模板和函数重载
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 重载==不适用于二进制树
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 重载运算符new[]的行为取决于析构函数
- 正在尝试重载二进制搜索树分配运算符
- 重载Singly Linked List中的赋值运算符
- 取消引用运算符不能重载