运算符重载+以添加多个对象

时间:2016-01-09 18:19:07

标签: c++ class overloading operator-keyword

我需要使用运算符重载添加多个对象,如下所示:

ex1 operator+(const ex1 &c1, const ex1 &c2, more++){
    return ex1(c1 + c2 + more++);
}

此函数添加了两个对象,但我想添加多个对象。这可能吗?

int main(){
  // first for example I want to add 3 objects
  ex1 ob1, ob2, ob3;
  ob1 + ob2 + ob3;

  code..
  code..

  // and after that I want to add for example 10 or more objects  
  ex1 ob1, ob2, ob3,..., ob10;
  ob1 + ob2 + ob3 +....+ ob10;
}

4 个答案:

答案 0 :(得分:2)

两个对象只需要overload +。如果您尝试添加三个或更多对象,它将自动运行,因为a + b + c等同于(a+b)+c,或者就操作符函数调用而言:

 operator+(operator+(a, b), c)

只要你从+例程中返回一个合适的类型,你应该没事。

如果你有一个对象数组并希望将它们全部加起来,那么你只需要为两个对象重载operator +,然后你可以使用std::accumulate中的<numeric>函数头:

std::vector<ex1> objects = {/*...lots of objects*/};
ex1 sum = std::accumulate(objects.begin(), objects.end(), ex1());

重新更新: 通过在C ++中重载运算符,您可以更改运算符的返回类型和语义,但不能更改以下任何内容:

  • 运算符的优先级(即,a+b*c不能等同于(a+b)*c
  • 运算符的arity(即你不能使一元运算符超载以获取2个操作数,反之亦然。例如,你不能使%work liks%a或%
  • 如果(一元)运算符是后缀或前缀,则无法更改,因此您无法使语法a-a+正常工作

所以第二个问题的答案是否定的。

答案 1 :(得分:2)

只需定义

ex1 operator+(const ex1 &c1, const ex1 &c2){
    return ex1(c1.inner_value + c2.inner_value);
}

然后

a + b + c

将被解释为

operator+(  operator+(a,b) , c )

所以它应该工作

答案 2 :(得分:1)

如果您希望重载的运算符适用于多个对象,您需要的是 chaining * ,当您通过引用返回结果时,可以确保这一点:

x.split(" ")

或者如果运营商是集体成员:

ex1& operator+(const ex1 &c1, const ex1 &c2){

    return ex1.var = c1.var + c2.var;
}

如果您具有上述定义,则可以按如下方式添加多个对象:

ex1& operator+(const ex1 &rhs) {

    return ex1.var = this.var + rhs.var; 
}

这相当于:

ex1 + ex2 + ex3

即。它总是简化为两个操作数之间的二进制运算。

要回答您更新的问题,以下是all the operators that could be overloaded的列表,无论其是否为arity(一元,二进制)或词缀(前缀,后缀)。在您更新的问题的情况下,您正在寻找postfix,一元运算符重载。

* 多个方法调用,其中每个方法返回一个对象,允许调用在一个语句中链接在一起,而不需要变量来存储中间结果

答案 3 :(得分:0)

除了一个例外,C ++只有一元运算符和二元运算符。唯一的例外是三元运算符,例如# Until the version *following* httr 1.0.0 is available on CRAN, get the # development version by uncommenting the following 2 lines # library(devtools) # install_github("hadley/httr") library(httr) # 1. Set up credentials fitbit_endpoint <- oauth_endpoint( request = "https://api.fitbit.com/oauth2/token", authorize = "https://www.fitbit.com/oauth2/authorize", access = "https://api.fitbit.com/oauth2/token") myapp <- oauth_app( appname = "data_access", key = "Your OAuth 2.0 Client ID", secret = "Your Client (Consumer) Secret") # 2. Get OAuth token scope <- c("sleep","activity") # See dev.fitbit.com/docs/oauth2/#scope fitbit_token <- oauth2.0_token(fitbit_endpoint, myapp, scope = scope, use_basic_auth = TRUE) # 3. Make API requests resp <- GET(url = "https://api.fitbit.com/1/user/-/sleep/date/2015-10-10.json", config(token = fitbit_token)) content(resp) 。关于x = condition ? 0 : 42;,这可以是一元运算符(例如operator+)或二元运算符(+42)。

您可以轻松创建一个自定义函数,该函数将三个40+2个对象作为输入,并以某种方式计算这三个对象的总和。但是,您无法调用此函数ex1。在C ++中,operator+没有地方可以接受三个参数。

围绕此限制有很多方法。最简单的方法是创建二进制operator+的重载,计算一对operator+对象的总和,创建一个新的ex1对象作为输出。声明ex1将导致两次调用ex1 d=a+b+c;。两者都将创建ex1 operator+(const ex1&, const ex1&)类型的临时对象。然后,将表示ex1值的临时值传递给a+b+c,以将该表达式的值分配给ex1::operator=

如果你反复这样做,那些临时对象的创建很可能代表性能瓶颈。如果您只是这样做了几次,那么性能瓶颈就不是问题了。您唯一需要担心的是这是否是一个问题,并确定是否是您需要解决的问题。

克服此性能瓶颈的一种方法是创建一个函数(或多个函数),这些函数将两个以上的对象作为输入并从这些多个对象创建一个总和。缺点是您无法命名此函数d,因此您无法使用operator+。你必须使用像d=a+b+c这样的东西。

另一种方法是使用expression templates作为实施lazy evaluation的方法。您的ex1::add_three(ex1&d, const ex1&a, const ex1&b, const ex1&c)实际上并未计算operator+(const ex1& a, constex1& b)。它改为创建一个最终将计算a+b的对象。表达式a+b反过来创建另一个最终将计算该结果的对象。最后,表达式a+b+c评估该表达式并将其分配给d=a+b+c,并且(如果正确实现)这样做而不创建任何临时表。

这种方法也有其缺点。有时最好创建一个临时的。 Eigen包非常好地确定何时更好地创建临时文件而不是使用推迟计算的表达式模板。