重载运算符[]

编程入门 行业动态 更新时间:2024-10-27 10:23:05
本文介绍了重载运算符[]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我之前没有发布到comp.lang.c ++(或comp.lang.c ++。moderated) 。一般来说,当我有一个C ++问题时,我会在 The C ++ Programming Language,Third Edition中寻找答案。作者:Stroustrup。 然而,我遇到了一个我无法回答的问题 The Book。或Google搜索(是的,至少我是RTFBed)。我希望这个新闻组中的某个人可能知道答案。 超载[]运营商 假设我想开发一个支持重载[] 运算符的类,并读取和写入int。类型。我认为 这样做的方式是: class MyClass { / / ... //理论上,RHS运算符 const int operator [](const int i)const; //理论上,LHS运营商 int& operator [](const int i); // ... } 这里RHS代表右手-side,或r值和LHS代表 左手边,或l值。 MyClass foo; int i = foo [j]; // RHS参考NOT! foo [j] = i; // LHS参考 令我惊讶的是,第一个声明是i = foo [j];似乎 调用重载的运算符我已经标记为LHS。我尝试使用 Microsoft的Visual C ++ 6.0编译器,我认为至少升级了 service pack 5(版本12.00.8804)和GNU 2.95.2 g ++编译器 for free on freeBSD。两个编译器都得到了相同的结果。 为了更具体的形式,我已经在下面提供了一个完整的测试 代码: #include< stdio.h> 类重载 { private: int * pArray; public: 重载(size_t size) { pArray = new int [size]; } ~重载() { delete [] pArray; } //理论上,RHS运算符 const int运算符[](const int i)const { printf(" RHS a [%2d] \ n",i); 返回pArray [i]; } //理论上,LHS运营商 int& operator [](const int i) { printf(" LHS a [%2d] \ n",i); 返回pArray [i]; } }; //重载 int main() { const int len = 4; 重载a(len); int b [len]; int i; printf(" initializing array ... \ n"); for(i = 0; i< len; i ++){ a [i] = i + 1; } printf(在''if''语句中读取数组中的值... \ n"); for(i = 0; i< len; i ++){ if(a [i]!= i + 1){ printf(坏值); 休息; } } printf(从赋值中的数组读取值... \ n); for(i = 0; i< len; i ++){ b [i] = a [i]; } printf(" expression ... \ n"); int j = a [1] + a [2]; 返回0; } 当我编译并执行此代码我得到 初始化数组... LHS a [0 ] LHS a [1] LHS a [2] LHS a [3] 读数值来自if语句中的数组... LHS a [0] LHS a [1] LHS a [ 2] LHS a [3] 读取作业中数组的值... LHS a [0] LHS a [1] LHS a [2] LHS a [3] 表达式...... LHS a [1] LHS a [2] 我期望初始化将参考LHS形式的 重载函数。然而,令我惊讶的是,'if'' 语句和值读数也引用了 重载运算符的LHS形式。我很惊讶这一点,因为我可以告诉我,这样我已经实现了重载的[]运算符是 几乎文本本书"方法。 有没有办法实现这个类,这样当RHS []似乎是一个r值时,它将被调用??那是 if(a [i]!= i + 1) b [i] = a [i]; int j = a [1] + a [2]; 在这个例子中,差异并不重要,因为代码得到预期结果 。但是,在参考计数对象的情况下,RHS和LHS 运营商的正确调用很重要, 这是最初激发这个问题的应用。 我正在研究引用计数字符串类的第三个版本, 可以在这里找到: www.bearcave/software/string/index.html 。这个类 遭受上述[]运算符 行为导致的错误。特别是它制作的副本太多了。 我已经注意到Stroustrup使用Cref类的解决方案(来自11.12 的The Book )。但是,在他的代码中,你似乎可以省略[]运算符的RHS版本。 我将不胜感激上面的测试代码的版本调用了RHS运算符,看起来是r值引用。可以 你请把这个帖子复制到iank at bearcave dot com。 谢谢你的帮助, Ian 在熊猫网上冲我来说 [见 www.gotw.ca/resources/clcm.htm 有关的信息] [comp.lang.c ++。主持。第一次海报:做到这一点! ]

I have not posted to comp.lang.c++ (or comp.lang.c++.moderated) before. In general when I have a C++ question I look for answers in "The C++ Programming Language, Third Edition" by Stroustrup. However, I''ve come upon a question that I can neither answer from "The Book" or a Google search (so yes, at least I RTFBed). I''m hoping that someone in this news group might know the answer. Overloading the [] Operator Say I want to develop a class that supports the overloaded [] operator and reads and writes the "int" type. I thought that the way this was done was: class MyClass { //... // in theory, the RHS operator const int operator[](const int i ) const; // in theory, the LHS operator int& operator[](const int i ); //... } Here RHS stands for right-hand-side, or an r-value and LHS stands for left-hand-side, or an l-value. MyClass foo; int i = foo[j]; // RHS reference NOT! foo[j] = i; // LHS reference Much to my surprise, the first statement "i = foo[j];" seems to invoke the overloaded operator I''ve labeled LHS. I tried this with Microsoft''s Visual C++ 6.0 compiler, I think upgraded with at least service pack 5 (version 12.00.8804) and the GNU 2.95.2 g++ compiler for Intel on freeBSD. Both compilers got the same results. To put things in more concrete form, I''ve included a complete test code below: #include <stdio.h> class overloaded { private: int *pArray; public: overloaded( size_t size ) { pArray = new int[ size ]; } ~overloaded() { delete [] pArray; } // in theory, the RHS operator const int operator[](const int i ) const { printf("RHS a[%2d]\n", i ); return pArray[i]; } // in theory, the LHS operator int& operator[](const int i ) { printf("LHS a[%2d]\n", i ); return pArray[i]; } }; // overloaded int main() { const int len = 4; overloaded a(len); int b[len]; int i; printf("initializing array...\n"); for (i = 0; i < len; i++) { a[i] = i + 1; } printf("reading values from array in an ''if'' statement...\n"); for (i = 0; i < len; i++) { if (a[i] != i+1) { printf("bad value"); break; } } printf("reading values from an array in an assignment...\n"); for (i = 0; i < len; i++) { b[i] = a[i]; } printf("expression...\n"); int j = a[1] + a[2]; return 0; } When I compile and execute this code I get initializing array... LHS a[ 0] LHS a[ 1] LHS a[ 2] LHS a[ 3] reading values from array in an ''if'' statement... LHS a[ 0] LHS a[ 1] LHS a[ 2] LHS a[ 3] reading values from an array in an assignment... LHS a[ 0] LHS a[ 1] LHS a[ 2] LHS a[ 3] expression... LHS a[ 1] LHS a[ 2] I expected that the "initialization" would reference the LHS form of the overloaded function. However, much to my surprise, the ''if'' statement and the value reads also referenced the LHS form of the overloaded operator. I''m surprised at this, since as far as I can tell, this way I''ve implemented the overloaded [] operators is pretty much "text book" approach. Is there a way to implement this class so that the RHS [] will be called when it seems to be an r-value? That is if (a[i] != i+1) b[i] = a[i]; int j = a[1] + a[2]; In this example the difference is not critical, since the code gets the expected results. However, proper invokation of the RHS and LHS operators is important in the case of reference counted objects, which is the appliction that originally motivated this question. I''m working on a third version of a reference counted String class, which can be found here: www.bearcave/software/string/index.html. This class suffers from a bug caused by the behavior of the [] operator described above. In particular, it is making too many copies. I have noted Stroustrup''s solution using the Cref class (from 11.12 of "The Book"). However, in his code it appears that you might as well omit the RHS version of the [] operator. I''d be grateful for a version of the test code above that invokes the RHS operator for what appear to be r-value references. Could you please copy any postings on this to "iank at bearcave dot com". Thank you for your help, Ian iank at bearcave dot com [ See www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]

推荐答案

"(null)" < IA ** @ idiom>在消息新闻中写道:1058054598.920916@smirk ... "(null)" <ia**@idiom> wrote in message news:1058054598.920916@smirk... 我之前没有发布到comp.lang.c ++(或comp.lang.c ++。moderated)。一般来说,当我有一个C ++问题时,我会在The C ++ Programming Language,Third Edition中寻找答案。作者:Stroustrup。然而,我遇到了一个我无法回答的问题。The Book或Google搜索(是的,至少我是RTFBed)。我希望这个新闻组中的某个人可能知道答案。 重载[]运算符 说我想开发一个支持的类重载的[] 运算符并读取和写入int类型。我认为这样做的方式是: 类MyClass { // ... //理论上,RHS运算符 const int operator [](const int i)const; //理论上,LHS运算符 int& operator [](const int i); // ... 我更喜欢 int operator [ ](int i)const; int& operator [](int i); 为int类型,其他const'是不必要的。 您对RHS运算符的评论然而,LHS操作员不正确。见下面的。 } 这里RHS代表右手边,或r值和LHS代表对于左手边或l值。 MyClass foo; int i = foo [j]; // RHS参考NOT! foo [j] = i; // LHS参考 令我惊讶的是,第一个声明是i = foo [j];似乎调用重载的运算符我已经标记为LHS。我尝试使用微软的Visual C ++ 6.0编译器,我认为至少升级了至少 Service Pack 5(版本12.00.8804)和GNU 2.95.2 g ++编译器对于英特尔在freeBSD上。两个编译器都得到了相同的结果。 [snip] 我期望初始化将参考LHS形式的重载函数。然而,令我惊讶的是,'if''语句和值读取也引用了重载运算符的LHS形式。我对此感到惊讶,因为据我所知,这样我实现了重载的[]操作符几乎是教科书。方法。 有没有办法实现这个类,这样当RHS []似乎是一个r值时,它会被调用?那是 如果(a [i]!= i + 1) b [i] = a [i]; int j = a [1] + a [ 2]; 如果你能做你想做但你不能做的事情会很好。 为了清晰起见用F表示operator [],用G表示operator =,然后 基本上你要求的是编译器区分 对F的调用 G(...,F(i)) 来自 G(F(i) ,...) 但编译器无法为任何正常函数执行此操作,因此没有 理由期望它适用于operator []和operator =。 在这个例子中,差异并不重要,因为代码得到了预期的结果。但是,RHS和LHS 操作员的正确调用在参考计数对象的情况下很重要,这是最初激发这个问题的应用。 我是处理引用的第三个版本的String类,可以在这里找到: www.bearcave/software/string/index.html 。这个类会受到上面描述的[]运算符行为导致的错误的影响。特别是它制作了太多的副本。 对,这就是为什么你应该避免运算符[]引用计数字符串 类。不可能以有效的方式实施。在非const引用计数字符串类上实现 operator []意味着妥协, 即使你必须立即获取字符串的副本 operator []可能只是用来读取字符串,或者你必须用写一个代理类(例如Stroustrup中的Cref)。 我已经注意到Stroustrup使用Cref类的解决方案(来自The Book的11.12 )。但是,在他的代码中,你似乎可以省略[]运算符的RHS版本。 I have not posted to comp.lang.c++ (or comp.lang.c++.moderated) before. In general when I have a C++ question I look for answers in "The C++ Programming Language, Third Edition" by Stroustrup. However, I''ve come upon a question that I can neither answer from "The Book" or a Google search (so yes, at least I RTFBed). I''m hoping that someone in this news group might know the answer. Overloading the [] Operator Say I want to develop a class that supports the overloaded [] operator and reads and writes the "int" type. I thought that the way this was done was: class MyClass { //... // in theory, the RHS operator const int operator[](const int i ) const; // in theory, the LHS operator int& operator[](const int i ); //... I''d prefer int operator[](int i ) const; int& operator[](int i ); for an int type the other const''s are unecessary. Your comments about RHS operator and LHS operator are incorrect however. See below. } Here RHS stands for right-hand-side, or an r-value and LHS stands for left-hand-side, or an l-value. MyClass foo; int i = foo[j]; // RHS reference NOT! foo[j] = i; // LHS reference Much to my surprise, the first statement "i = foo[j];" seems to invoke the overloaded operator I''ve labeled LHS. I tried this with Microsoft''s Visual C++ 6.0 compiler, I think upgraded with at least service pack 5 (version 12.00.8804) and the GNU 2.95.2 g++ compiler for Intel on freeBSD. Both compilers got the same results. [snip] I expected that the "initialization" would reference the LHS form of the overloaded function. However, much to my surprise, the ''if'' statement and the value reads also referenced the LHS form of the overloaded operator. I''m surprised at this, since as far as I can tell, this way I''ve implemented the overloaded [] operators is pretty much "text book" approach. Is there a way to implement this class so that the RHS [] will be called when it seems to be an r-value? That is if (a[i] != i+1) b[i] = a[i]; int j = a[1] + a[2]; It would be nice if you could do what you want to do but you can''t. For clarity lets denote operator[] by F, and operator= by G, then essentially what you are asking for is the compiler to distinguish between calls to F in G(...,F(i)) from G(F(i), ...) But the compiler cannot do this for any normal function so there is no reason to expect it to work for operator[] and operator=. In this example the difference is not critical, since the code gets the expected results. However, proper invokation of the RHS and LHS operators is important in the case of reference counted objects, which is the appliction that originally motivated this question. I''m working on a third version of a reference counted String class, which can be found here: www.bearcave/software/string/index.html. This class suffers from a bug caused by the behavior of the [] operator described above. In particular, it is making too many copies. Right, which is why you should avoid operator[] on reference counted string classes. It is impossible to implement in an efficient manner. Implementing operator[] on a non-const reference counted string class means a compromise, either you have to take a copy of the string immediately even though operator[] might only be being used to read from the string, or you have to write a proxy class (e.g. Cref in Stroustrup). I have noted Stroustrup''s solution using the Cref class (from 11.12 of "The Book"). However, in his code it appears that you might as well omit the RHS version of the [] operator.

那么没有RHS版本的[你被误导了。如果你从Stroustrup的代码中省略了 运算符[]的const版本,那么以下 将无法编译 const String x =" abc"; cout<< x [0]; 这是operator []的const版本的真正含义,它允许你 来访问const对象。与任何其他const方法相同。 john

Well there is no RHS version of [] you have been misinformed. If you omitted the const version of operator[] from Stroustrup''s code then the following would not compile const String x = "abc"; cout << x[0]; This is the true meaning of the const version of operator[], it allows you to access const objects. Same as any other const method. john

> 我正在工作在引用的第三个版本上计算了String类,可以在这里找到: www.bearcave/software/string/index.html 。这个类会受到上面描述的[]运算符行为导致的错误的影响。特别是它制作了太多的副本。 I''m working on a third version of a reference counted String class, which can be found here: www.bearcave/software/string/index.html. This class suffers from a bug caused by the behavior of the [] operator described above. In particular, it is making too many copies.

BTW,来自上面的网站 "当一个STL字符串对象被分配给另一个字符串对象,副本是 。相比之下,String容器复制一个引用并递增一个 引用计数。 这不是严格正确的,标准将它留给了 实现是否使用引用计数。我的版本 STL(dinkumware)确实使用引用计数。 john

BTW, from the above site "When an STL string object is assigned to another string object, a copy is made. In contrast, the String container copies a reference and increments a reference count." This is not strictly correct, the standard leaves it up to the implementation whether to use reference counting or not. My version of the STL (dinkumware) does use reference counting. john

"(null)" schrieb: "(null)" schrieb: class MyClass { // ... //理论上,RHS运算符 const int运算符[ ](const int i)const; //理论上,LHS运营商 int& operator [](const int i); // ... } 所有这些成员都在班级的私人部分。 我假设你错过了一个公共:在某个地方。 这里RHS代表右手边,或者r值和LHS代表左手边,或者l -value。 MyClass foo; int i = foo [j]; // RHS参考NOT! foo [j] = i; // LHS参考 令我惊讶的是,第一个声明是i = foo [j];似乎调用重载的运算符我已经标记为LHS。 class MyClass { //... // in theory, the RHS operator const int operator[](const int i ) const; // in theory, the LHS operator int& operator[](const int i ); //... } All these members are in the private section of the class. I assume you missed a "public:" somewhere. Here RHS stands for right-hand-side, or an r-value and LHS stands for left-hand-side, or an l-value. MyClass foo; int i = foo[j]; // RHS reference NOT! foo[j] = i; // LHS reference Much to my surprise, the first statement "i = foo[j];" seems to invoke the overloaded operator I''ve labeled LHS.

一点也不奇怪。 你的foo-object是非const的,所以编译器调用非const 重载的运算符[]。 为什么要调用const版本? 当foo定义为const时,情况完全不同: const MyClass foo; 那么编译器当然会,调用operator []的const-version。 注意,如果你在调用时使用重载运算符[],这个重载决议与事实无关。网站作为LHS或RHS。 问候, Thomas [见 www.gotw.ca/resources/clcm.htm 了解有关的信息/> [comp.lang.c ++。moderated。第一次海报:做到这一点! ]

No surprise at all. Your foo-object is non-const, so the compiler invokes the non-const overloaded operator[]. Why should it invoke the const version? Things are totally different when foo is defined as const: const MyClass foo; Then the compiler will, of course, invoke the const-version of operator[]. Note that this overload resolution has nothing to do with the fact if you use your overloaded operator[] at the call site as LHS or RHS. regards, Thomas [ See www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]

更多推荐

重载运算符[]

本文发布于:2023-06-03 12:14:41,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/473710.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:运算符

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!