Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;运算符重载 为什么C++程序下面输出“ACCA”?为什么调用了两次操作符int() #include "stdafx.h" #include <iostream> using namespace std; class Base { public: Base(int m_var=1):i(m_var){ cout<<"A"; } Base(Base& Base){ cout<<"B"; i=Base.i; } operator int() { cout<<"C"; return i; } private: int i; }; int main() { Base obj; obj = obj+obj; return 0; } #包括“stdafx.h” #包括 使用名称空间std; 阶级基础{ 公众: 基数(int m_var=1):i(m_var){ cout_C++_Class_Operator Overloading - Fatal编程技术网

C++;运算符重载 为什么C++程序下面输出“ACCA”?为什么调用了两次操作符int() #include "stdafx.h" #include <iostream> using namespace std; class Base { public: Base(int m_var=1):i(m_var){ cout<<"A"; } Base(Base& Base){ cout<<"B"; i=Base.i; } operator int() { cout<<"C"; return i; } private: int i; }; int main() { Base obj; obj = obj+obj; return 0; } #包括“stdafx.h” #包括 使用名称空间std; 阶级基础{ 公众: 基数(int m_var=1):i(m_var){ cout

C++;运算符重载 为什么C++程序下面输出“ACCA”?为什么调用了两次操作符int() #include "stdafx.h" #include <iostream> using namespace std; class Base { public: Base(int m_var=1):i(m_var){ cout<<"A"; } Base(Base& Base){ cout<<"B"; i=Base.i; } operator int() { cout<<"C"; return i; } private: int i; }; int main() { Base obj; obj = obj+obj; return 0; } #包括“stdafx.h” #包括 使用名称空间std; 阶级基础{ 公众: 基数(int m_var=1):i(m_var){ cout,c++,class,operator-overloading,C++,Class,Operator Overloading,操作符int()被调用两次,因为您没有重载操作符+。编译器不知道如何将基添加到基,因此它们被转换为int(因为您教会了它如何做),它知道如何做。下面的代码打印ADA: #include <iostream> using namespace std; class Base { public: Base(int m_var=1):i(m_var){ cout<<"A"; } Base(Base& Base){

操作符int()
被调用两次,因为您没有重载
操作符+
。编译器不知道如何将
添加到
,因此它们被转换为
int
(因为您教会了它如何做),它知道如何做。下面的代码打印
ADA

#include <iostream>

using namespace std;

class Base {
public:
    Base(int m_var=1):i(m_var){
        cout<<"A";
    }
    Base(Base& Base){
        cout<<"B";
        i=Base.i;
    }
    operator int() {
        cout<<"C";
        return i;
    }
    int operator+(Base& Base)
    {
        cout<<"D";
        return i+Base.i;
    }
private:
    int i;
};

int main()
{
    Base obj;
    obj = obj+obj;
    return 0;
}
#包括
使用名称空间std;
阶级基础{
公众:
基数(int m_var=1):i(m_var){

cout您可以在表达式
obj+obj
中引用obj两次,并且每个这样的引用都必须转换为一个整数


这种转换可能是“有状态的”(stateful),这并非不可能(尽管这是一个可怕的想法),也就是说,通过设计,每次调用它时都会返回不同的值。毕竟,
obj
表示的值可能会改变(可能是计数器或类似的东西)因此编译器必须为每个引用重新计算它。

每个操作数调用它一次,不管它是否是同一个实例

 obj = obj+obj;
它将第一个操作数“强制”为int,然后将第二个操作数“强制”为int


如果要避免此隐式强制转换,则需要重载运算符+。

它调用
运算符int()
两次,因为它需要将两个obj都转换为int,然后才能添加它们。

构造对象时,会得到第一个“A”:

当您指定添加
obj+obj
时,编译器需要找出一种在
obj
上使用
+
的方法。由于您没有为
Base
重写
运算符+
,因此会对等式的每一侧调用到
int()
的转换:

obj+obj
这将打印
“CC”

然后,您将分配给
obj
,它的类型为
Base
,因此可以从
int()
操作符接受int(
i+i
)的构造函数将运行,并打印“A”:

首先,这一行:

Base obj;
Base obj;
obj = obj + obj
默认值通过选择接受整数的构造函数来构造对象
obj
,默认值为
1
。这负责将第一个
A
打印到标准输出

obj = obj+obj;
      ^^^--------obj converted to int here
          ^^^----obj converted to int here
^^^^^------------Base(int) ctor and default operator= called here
然后,这个表达式:

obj + obj
需要选择一个可行的重载
运算符+
。在这种情况下,由于
obj
有一个用户定义的到
int
的转换,因此选择内置的
运算符+
,并将两个参数转换为
int
。这负责将两个
C
打印到标准输出

obj = obj+obj;
      ^^^--------obj converted to int here
          ^^^----obj converted to int here
^^^^^------------Base(int) ctor and default operator= called here
然后,在以下步骤中分配给
obj

obj = obj + obj
需要为
Base
调用隐式生成的
运算符=
。隐式生成的
运算符=
具有签名:

Base& operator = (Base const&);
这意味着等号右侧的表达式(类型为
int
)必须转换为临时
Base
对象,从中分配
obj
(隐式生成的
运算符=
的引用参数绑定到此临时对象)

但是从
int
创建这个临时文件反过来需要调用
Base
的转换结构,它再次接受
int
,这负责将第二个
A
打印到标准输出

obj = obj+obj;
      ^^^--------obj converted to int here
          ^^^----obj converted to int here
^^^^^------------Base(int) ctor and default operator= called here
除非您了解成本,并且知道在您的特定情况下,收益大于成本,否则重载cast操作符通常不是一个好主意。

第一个a来自

Base obj;

这两个Cs来自于将
obj+obj
中的obj转换为
int
,因为您没有重载
操作符+

最后一个A来自结果
int
obj
obj=
转换

< C++程序如何计算“ACCA”?< /P> 显示的第一个字母是“A”。此输出与此行相关:

Base obj;
Base obj;
obj = obj + obj
…您正在其中创建新的Base实例

下一行有点复杂:

obj = obj+obj;
通常,这会转换为
obj.operator+(obj)
,但在类
Base
中没有重载operator+,因此此转换无效。剩余的可能性是operator+实际上是数字加法运算符

是的,这是可能的,因为您提供了对
int
的转换。因此可以在
int
中转换方程的每个项……因此
运算符int
被调用两次。调用
运算符int
的实际次数取决于激活的优化。例如,编译器可以意识到这两个术语是相同的,然后在第一次调用
运算符int
后创建一个新的临时值。在这种情况下,您将看到CA而不是CC

最后,赋值表达式
obj.operator=(temp)
被执行。这里的关键字是temp。为了让
操作符=
工作,因为它没有重载,你必须在右边有一个
Base
对象。实际上可以有它,因为
Base
使用
int
来构建新实例。好的,
obj+o的结果是这样的bj
是一个
int
(假设它被称为'x')号,编译器创建了一个类
Base
的临时对象,该对象是用数字x构造的,如下所示:

Base temp( x );
这就是看到的最后一个字母是“A”的方式。同样,许多编译器可以避免在某些情况下构建临时字母,因此在结尾处可能看不到“A”

请注意,这一行:

Base obj;
Base obj;
obj = obj + obj
因此分解为:

int x = ( (int) obj ) + ( (int) obj );
Base temp( x );
obj = temp;
最终指令的结果就像备忘录一样