gpt4 book ai didi

c++ - 方括号 [] 运算符重载 c++

转载 作者:行者123 更新时间:2023-11-28 05:14:17 25 4
gpt4 key购买 nike

我有一个项目要我用 C++ 制作一个 BigNum 类(大学项目)它说要为 get 和 set 重载运算符括号但问题是如果集合无效,我们应该抛出一个异常,无效的就像

BigNum a;
a[i]=11;//it is invalid because its >9

在搜索中我发现了如何让这个集合工作

C++ : Overload bracket operators [] to get and set

但我没有找到如何在 c# 中管理设置操作你可以轻松地管理设置值,它在 c++ 中的等价物

为了在 C# 中表达清楚,我们可以说

public int this[int key]
{
set
{
if(value<0||value>9)throw new Exception();
SetValue(key,value);
}
}

最佳答案

新答案

我必须重写我的答案,我的旧答案是一场灾难。

检查应该在分配期间进行,当右侧 ( 11 ) 可用时。所以你需要重载的运算符是 operator= .用于重载operator= ,至少其操作数之一必须是用户定义的类型。在这种情况下,唯一的选择是左侧。

这里的左侧是表达式 a[i] .此表达式的类型,也就是 operator[] 的返回类型, 必须是用户定义的类型,比如 BigNumberElement .然后我们可以声明一个 operator=对于 BigNumberElement并在 operator= 的主体内进行范围检查.

class BigNum {
public:
class BigNumberElement {
public:
BigNumberElement &operator=(int rhs) {
// TODO : range check
val_ = rhs;
return *this;
}

private:
int val_ = 0;
};

BigNumberElement &operator[](size_t index) {
return element_[index];
}

BigNumberElement element_[10];
};

旧答案

你可以定义一个 wapper,比如说 NumWapper ,它包装了 BigNum 元素的引用。 operator= BigNum 按值返回包装器。

a[i]=11;

则类似于 NumWrapper x(...); x = 11 .现在您可以在 operator= 中进行这些检查的 NumWrapper .


class BigNum {
public:
NumWrapper operator[](size_t index) {
return NumWrapper(array_[index]);
}

int operator[](size_t index) const {
return array_[index];
}
};

在NumWrapper中,重载一些运算符,例如:

class NumWrapper {
public:
NumWrapper(int &x) : ref_(x) {}
NumWrapper(const NumWrapper &other) : ref_(other.ref_) {}

NumWrapper &operator=(const NumWrapper &other);
int operator=(int x);
operator int();

private:
int &ref_;
};

您还可以将 NumWrapper 的复制和移动构造函数声明为私有(private),并使 BigNum 成为他的 friend ,以防止用户代码复制您的包装器。这样的代码auto x = a[i]如果你这样做将不会编译,而用户代码仍然可以通过 auto x = static_cast<T>(a[i]) 复制包装值(虽然有点冗长)。

auto &x = a[i]; // not compiling
const auto &x = a[i]; // dangerous anyway, can't prevent.

看来我们很好。


这也是另一种方法:将元素存储为用户定义的类,比如 BigNumberElement .我们现在将类 BigNum 定义为:

class BigNum {
// some code
private:
BigNumberElement array_[10];
}

我们需要为 BigNumberElement 声明一整套操作符,例如比较(也可以通过转换来完成)、赋值、构造函数等,以便于使用。

auto x = a[i]现在将获得 BigNumberElement 的拷贝,这在大多数情况下都很好。只分配给它有时会抛出异常并引入一些运行时开销。但是我们仍然可以写auto x = static_cast<T>(a[i]) (虽然仍然很冗长......)。据我所知,意外的编译时错误消息比意外的运行时异常要好。

我们还可以使 BigNumberElement 不可复制/可移动...但是这与第一种方法相同。 (如果任何成员函数返回 BigNumberElement & ,意外的运行时异常就会返回。)

关于c++ - 方括号 [] 运算符重载 c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42975152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com