Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何重载类的任意二进制或一元运算符?

如何重载类的任意二进制或一元运算符?
EN

Stack Overflow用户
提问于 2017-10-07 13:47:13
回答 1查看 141关注 0票数 2

假设有一个继承数组x的类,添加了一些参数p

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
classdef test
    properties
       x
       p
    end
    methods
       function t=calculate(t)
           [t.x,t.p]=calc(x,p);
       end
       function t=plus(t1,t2)
           t.x=t1.x+t2.x;
       end
   end
end

众所周知,如何重载二进制运算符,如plusmtimesminus等。如何为启用重载任何二进制矢量化运算符,或最终启用任何一元运算符,如meanabsmax等,以便直接应用于向量x?例如,如何使S = mean(S);S.x = mean(S.x);等效

EN

回答 1

Stack Overflow用户

发布于 2017-10-24 21:42:15

如果我正确理解您的问题,听起来您希望您的新类test只继承为属性x类定义的所有二进制和一元方法(并在调用它们时对属性x进行操作),这样您就不必自己重新定义它们。

如果这是您想要的,那么我认为做类似事情的唯一可行方法是实际使用继承并使类test成为属性x类的子类。考虑到x只是一个double的简单情况,可以找到一个对内置double类型进行子类分类的好示例这里。将该示例调整为您的示例,下面是实现类test的一种方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
classdef test < double

  properties
    p
  end

  methods
    function obj = test(x, p)
      if (nargin < 2)
        p = 0;
        if (nargin < 1)
          x = 0;
        end
      end
      obj@double(x);
      obj.p = p;
    end

    function sref = subsref(obj, s)
      switch s(1).type
        case '.'
          switch s(1).subs
            case 'p'
              sref = obj.p;
            case 'x'
              x = double(obj);
              if (length(s) < 2)
                sref = x;
              elseif (length(s) > 1) && strcmp(s(2).type, '()')
                sref = subsref(x, s(2:end));
              end
            otherwise
              error('Not a supported indexing expression')
          end
        case '()'
          x = double(obj);
          newx = subsref(x, s(1:end));
          sref = test(newx, obj.p);
        case '{}'
          error('Not a supported indexing expression')
      end
    end

    function obj = subsasgn(obj, s, b)
      switch s(1).type
        case '.'
          switch s(1).subs
            case 'p'
              obj.p = b;
            case 'x'
              if (length(s) < 2)
                obj = test(b, obj.p);
              elseif (length(s) > 1) && strcmp(s(2).type, '()')
                x = double(obj);
                newx = subsasgn(x, s(2:end), b);
                obj = test(newx, obj.p);
              end
            otherwise
              error('Not a supported indexing expression')
          end
        case '()'
          x = double(obj);
          newx = subsasgn(x, s(1), b);
          obj = test(newx, obj.p);
        case '{}'
          error('Not a supported indexing expression')
      end
    end

    function disp(obj)
      fprintf('p:');
      disp(obj.p);
      fprintf('x:');
      disp(double(obj));
    end
  end

end

请注意:在类test的对象上使用test运算符和方法所得到的结果将返回double类的结果,而不是您想要的test。要获得您想要的行为,每次都必须将结果重新分配到属性x,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>> a = test(1:3, pi)  % Create an object with p = pi, and x = [1 2 3]

a = 
p:   3.141592653589793
x:     1     2     3

>> a.x = -a  % Unary operation on a, and reassignment to x

a = 
p:   3.141592653589793
x:    -1    -2    -3

>> a.x = a+4  % Binary operation and reassignment

a = 
p:   3.141592653589793
x:     3     2     1

>> a.x = mean(a)  % Another unary operation and reassignment

a = 
p:   3.141592653589793
x:     2
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46625426

复制
相关文章
【C++】运算符重载 ⑥ ( 一元运算符重载 | 后置运算符重载 | 前置运算符重载 与 后置运算符重载 的区别 | 后置运算符重载添加 int 占位参数 )
讲解了 前置运算符 的 重载 , 前置运算符就是 ++Object 或 --Object , 一元运算符 在 对象的 前面 ;
韩曙亮
2023/10/15
1550
【C++】运算符重载 ⑥ ( 一元运算符重载 | 后置运算符重载 | 前置运算符重载 与 后置运算符重载 的区别 | 后置运算符重载添加 int 占位参数 )
【C++】运算符重载 ⑥ ( 一元运算符重载 | 后置运算符重载 | 前置运算符重载 与 后置运算符重载 的区别 | 后置运算符重载添加 int 占位参数 )
讲解了 前置运算符 的 重载 , 前置运算符就是 ++Object 或 --Object , 一元运算符 在 对象的 前面 ;
韩曙亮
2023/10/15
1410
【C++】运算符重载 ⑥ ( 一元运算符重载 | 后置运算符重载 | 前置运算符重载 与 后置运算符重载 的区别 | 后置运算符重载添加 int 占位参数 )
C++重载一元前缀/后缀运算符
重载一元前缀运算符的时候,重载函数应该是这样的: operator++() 而重载一元后缀运算符的时候,重载函数是这样的 operator++(int) 注意,这里的参数不管是在声明还是在实现中,都不需要带上变量名。 并且,重载后缀运算符的时候,需要返回变量在被改变之前的值。
灯珑LoGin
2022/10/31
3230
【C++】运算符重载 ⑭ ( 逻辑与 && 运算符重载 | 逻辑或 || 运算符重载 | 完整代码示例 )
逻辑与 && 和 逻辑或 || 运算符 是 可以重载的 , 这两个操作符是 特殊操作符 ;
韩曙亮
2023/10/15
1830
【C++】运算符重载 ⑭ ( 逻辑与 && 运算符重载 | 逻辑或 || 运算符重载 | 完整代码示例 )
【C++】运算符重载 ⑦ ( 一元运算符重载 | 后置运算符重载 | 使用 全局函数 实现 后置 ++ 自增运算符重载 | 使用 成员函数 实现 后置 -- 自减运算符重载 )
韩曙亮
2023/10/15
2100
【C++】运算符重载 ⑦ ( 一元运算符重载 | 后置运算符重载 | 使用 全局函数 实现 后置 ++ 自增运算符重载 | 使用 成员函数 实现 后置 -- 自减运算符重载 )
【C++】运算符重载 ② ( 类内部定义云算符重载 - 成员函数 | 类外部定义运算符重载 - 全局函数 | 可重载的运算符 )
当使用 + 将 个对象相加时 , C++ 编译器会查找是否有定义运算符重载函数 ;
韩曙亮
2023/10/15
2700
【C++】运算符重载 ⑤ ( 一元运算符重载 | 使用 成员函数 实现 前置 ++ 自增运算符重载 | 使用 成员函数 实现 前置 - - 自减运算符重载 )
韩曙亮
2023/10/15
1920
【C++】运算符重载 ⑤ ( 一元运算符重载 | 使用 成员函数 实现 前置 ++ 自增运算符重载 | 使用 成员函数 实现 前置 - - 自减运算符重载 )
【C++】运算符重载 ④ ( 一元运算符重载 | 使用 全局函数 实现 前置 ++ 自增运算符重载 | 使用 全局函数 实现 前置 - - 自减运算符重载 )
为了使全局函数中能访问 Student 类的私有成员 , 需要将该全局函数声明为 友元函数 ;
韩曙亮
2023/10/15
2080
【C++】运算符重载 ④ ( 一元运算符重载 | 使用 全局函数 实现 前置 ++ 自增运算符重载 | 使用 全局函数 实现 前置 - - 自减运算符重载 )
python类的继承与运算符重载
Officially, CPython has no rule at all for when exactly overridden method of subclasses of built-in types get implicitly called or not. As an approximation, these methods are never called by other built-in methods of the same object. For example, an overridden __getitem__() in a subclass of dict will not be called by e.g. the built-in get() method.
哒呵呵
2018/08/06
8740
【C++】运算符重载案例 - 字符串类 ⑤ ( 重载 大于 > 运算符 | 重载 小于 < 运算符 | 重载 右移 >> 运算符 - 使用全局函数重载 | 代码示例 )
左移 << 操作符 cout << s << endl , 是将 s 对象输出到 cout 标准输出流中 ;
韩曙亮
2023/10/15
5480
C++重载运算符练习--对people类重载“= =”运算符和“=”运算符
题目描述 对people类重载“= =”运算符和“=”运算符,“==”运算符判断两个people类对象的id属性是否相等;“=”运算符实现people类对象的赋值操作。 代码如下 #include<iostream> #include<string> using namespace std; class Data{ public: Data(){} Data(int yy,int mm,int dd){ year=yy; month=mm; day=dd;
Enterprise_
2018/05/18
3.2K2
C++重载运算符练习--对people类重载“= =”运算符和“=”运算符
题目描述 对people类重载“= =”运算符和“=”运算符,“==”运算符判断两个people类对象的id属性是否相等;“=”运算符实现people类对象的赋值操作。 代码如下 #include<iostream> #include<string> using namespace std; class Data{ public: Data(){} Data(int yy,int mm,int dd){ year=yy; month=mm; day=dd;
Enterprise_
2019/03/01
3810
C++重载运算符练习--对people类重载“= =”运算符和“=”运算符
【C++】运算符重载 ⑧ ( 左移运算符重载 | 友元函数 / 成员函数 实现运算符重载 | 类对象 使用 左移运算符 )
上述 运算符重载 既可以使用 成员函数 进行重载 , 又可以使用友元函数进行重载 ;
韩曙亮
2023/10/15
2870
【C++】运算符重载 ⑧ ( 左移运算符重载 | 友元函数 / 成员函数 实现运算符重载 | 类对象 使用 左移运算符 )
【Groovy】Groovy 运算符重载 ( 运算符重载 | 运算符重载对应方法 )
Groovy 类可以进行运算符重载 , 任何一个类都可以使用预定义的 运算符 进行运算 , 如 " + - * / " 加减乘除 操作 , Groovy 中支持
韩曙亮
2023/03/30
2.8K0
【Groovy】Groovy 运算符重载 ( 运算符重载 | 运算符重载对应方法 )
运算符重载之左移运算符重载
左移运算符重载 #include<iostream> using namespace std; class wood { friend ostream& operator<<(ostream& cout, wood& d); public: wood(int num):num(num){} private: int num; }; //左移运算符重载只能用全局函数 ostream& operator<<(ostream& cout, wood& d) { cout << "木头的数量为" << d.
大忽悠爱学习
2021/02/22
5350
运算符重载之递增运算符重载
递增运算符重载 #include <iostream> using namespace std; //声明类 class wood { friend ostream& operator<<(ostream& cout, wood myint); public: //默认构造函数将m_Num初始化为0 wood() { m_Num = 0; } //前置递增++ //如果不用引用,就是调用重载函数,调用完之后就销毁(因为放在栈区) //引用是别名,调用地址 wood& opera
大忽悠爱学习
2021/02/22
3690
【C++】成员函数重载二元和一元运算符
重载双目运算符时,运算符函数中应该具有两个参数,若运算符函数作为类的成员函数(当运算符重载函数作为类的成员函数时,要求操作数左边必须是一个对象,而函数的参数可以是同类的对象也可以是普通的变量),则只需要一个参数。
谙忆
2021/01/21
5380
【C++】成员函数重载二元和一元运算符
【C++】运算符重载案例 - 字符串类 ④ ( 重载 双等号 == 运算符 | 重载 不等号 != 运算符 | 代码示例 )
韩曙亮
2023/10/15
3350
运算符重载之加号运算符重载
加号运算符重载 运算符重载:对已有运算符的重新定义,赋予其另一种功能,以适应不同的数据类型 #include<iostream> using namespace std; class pig{ public: int kilogram; //重量 int price; //价钱 //成员函数重载+号运算符 //pig operator+(pig& p) //{ // pig temp; // temp.kilogram = this->kilogram + p.kilogram;
大忽悠爱学习
2021/02/22
6730
运算符的重载
这是一串简单的类代码,比较重要的是sum()函数,注意到了参数是引用但是返回类型不是引用。将参数声明作为引用的目的只是为了提高效率,传递引用速度更快,使用的内存更少。 看一下输出内容QAQ
用户8247415
2021/04/13
5100

相似问题

如何重载一元/运算符?

12

重载一元运算符&

60

重载+/-一元运算符

63

重载的“operator+”必须是一元或二进制运算符错误

36

一元运算符重载:风险?

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文