#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<complex>
using namespace std; class Complex{
//复数为直角坐标形式,a+bj
private:
double real;
double image;
public:
Complex() :real(), image(){};// default constructor,初始化为0
Complex(double real, double image){ this->real = real; this->image = image; }//提供来了Complex c(0,1)的初始形式
Complex(const Complex& rhs){ (*this).real = rhs.real; image = rhs.image; }
~Complex(){ /*cout << "deconstructor called\n";*/ }
double getReal()const{ return real; }
double getImage()const{ return image; } //operator overload
Complex operator + (const Complex&rhs) //不能返回局部变量的引用,因为返回的是变量本身,变量随着函数结束会销毁掉
{
Complex result;
result.real= real + rhs.real;
result.image = image + rhs.image;
return result;
}
Complex operator-(const Complex&rhs) //注释掉的代码有错误,b-a得到一个表达式值,但b和a的值本身是没变的
{
/*real = real - rhs.real;
image = image - rhs.image;
return *this;*/
Complex result;
result.real = real - rhs.real;
result.image = image - rhs.image;
return result;
}
Complex&operator=(const Complex&rhs)
{
cout << "= called\n";
//简化版本
real = rhs.real;
image = rhs.image;
return *this;
}
/*ostream& operator<< (ostream&os)// 调用形式不符合平时输出习惯
{
if (image<0)
os << real << image << "j" ;
else os << real << "+" << image << "j";
return os;
}*/
friend ostream& operator<<(ostream&os ,const Complex &lhs);
};
ostream& operator<<(ostream&os, const Complex &lhs)
{
if (lhs.image < ) os << lhs.real << lhs.image << "j";
else os << lhs.real << "+" << lhs.image << "j";
return os;
}
int main()
{
Complex a; //申请的内存分配在栈上
/*a << cout<<endl;*/
Complex b(, );
/*b << cout << endl;*/
Complex c(b); Complex d = b+c;//=是初始化,调用拷贝构造函数,而不是重载运算符=
/*d << cout << endl;*/
Complex e(, -);
/*e << cout << endl;
b << cout << endl;*/
a = b + e;
a = b - e;
/*a << cout << endl;*/
Complex f = { , };
cout << a << "\n" << b << "\n" << c << endl;
cout << d << "\n" << e<<"\n" << f << endl;
vector<Complex> cv();
cv.push_back(f);
for (auto x:cv)
{
cout << x << endl;
} }

一些问题:

假设自定义了一个Complex类

Q:为什么需要自定义默认构造函数?

A:相比需要显示提供参数的constructor,前者不需要用户提供初始值,如Complex s,如果要用vector容纳Complex对象,要求Complex有自定义的默认构造函数,如下用法才能work:

Vector<Complex> cv(n),n个默认初始化的复数对象。

Q:定义单参构造函数有什么问题?

A:单参构造函数是一个隐式转换函数,如Complex c=7,会把右边的int转换为一个复数对象,加上explicit修饰该函数,能禁止这种隐式转换,只能使用直接初始化形式:Complex c(7)

Q:copy constructor的参数必须是引用,编译器禁止使用类型参数

A:如果是类型参数,Complex(Complex arg),参数传递时会构造实参的一个副本,循环调用拷贝构造函数,如果参数是引用,Complex(Complex&arg),使用的是实参本身,而且必须要加上const,因为non-const引用不接受const引用类型的实参。

Q:Complex的析构函数,deconstructor的函数体写法?

A:复数有两个private成员,都是double,析构时需要做什么工作?如果成员变量有指针,可以把指针置为空。

Q:重载输出运算符,只能overload为该类的友元函数?

A:如果是成员函数,ostream& operator<<(ostream& os),使用时的形式为c.operator<<cout<<endl或c<<cout<<endl;如果是非成员函数,要访问私有变量,需要在类内声明为友元:friend ostream& operator<<(ostream& os,const Complex&rhs ),调用形式为:cout<<c<<endl;

Q:重载赋值运算符与拷贝初始化的区别?

A:Complex a=c;这调用了copy ctr,而不是assingn operator,a=c+c,调用了重载的operator+和operator=,编译器如何区分调用哪一种函数?

c++primer,自定义一个复数类的更多相关文章

  1. C++ 实验 使用重载运算符实现一个复数类

    实验目的: 1.掌握用成员函数重载运算符的方法 2.掌握用友元函数重载运算符的方法 实验要求: 1.定义一个复数类,描述一些必须的成员函数,如:构造函数,析构函数,赋值函数,返回数据成员值的函数等. ...

  2. JavaScript实现一个复数类

    <script type="text/javascript"> /** * 这里定义Complex类,用来描述复数 */ /** * 这个构造函数为它所创建的每个实例定 ...

  3. Java自定义一个字典类(Dictionary)

    标准Java库只包含Dictionary的一个变种,名为:Hashtable.(散列表) Java的散列表具有与AssocArray相同的接口(因为两者都是从Dictionary继承来的).但有一个方 ...

  4. java中自定义一个异常类 在某些情况抛出自定的异常 ----------阻断程序

    //=============定义异常类 package org.springblade.flow.engine.errorException; /** * 自定义异常处理写入sap失败 */ pub ...

  5. Python自定义一个数组类,支持数组之间的四则运算和其他常见方法

    class MyArray: '''保证输入的内容是整型.浮点型''' def ___isNumber(self, num): if not isinstance(num, (int,float)): ...

  6. 定义一个复数类Complex

    #include<iostream> #include<math.h> using namespace std; class Complex{ public: Complex( ...

  7. 复数类(C++练习一)

    写一个复数类,实现基本的运算,目的熟悉封装与数据抽象. 类的定义 #include <iostream> #include <vector> using namespace s ...

  8. 安卓开发37:自定义的HorizontalScrollView类,使其pageScroll的时候焦点不选中

    自定义一个HorizontalScrollView类,主要为了让这个HorizontalScrollView不能鼠标点击,不能左右按键,并且没有焦点. public class ImageMoveHo ...

  9. C++习题 复数类--重载运算符2+

    Description 定义一个复数类Complex,重载运算符"+",使之能用于复数的加法运算.参加运算的两个运算量可以都是类对象,也可以其中有一个是整数,顺序任意.例如,c1+ ...

随机推荐

  1. Codeforce 1175 D. Array Splitting

    新鲜热乎的题 Codeforce 1175 D. 题意:给出一个长度为$n$的序列$a$,你需要把它划分为$k$段,每一个元素都需要刚好在其中一段中.分好之后,要计算$\sum_{i=1}^{n} ( ...

  2. 【TWRP】使用adb sideload线刷ROM的方法

    本教程详细介绍 手机刷三方ROM 之前需要安装的 TWRP 这个神器工具 楼主的手机是小米,所以此教程以小米手机为例.其他手机原理类似 第一步,解锁引导程序 访问小米的官方解锁网站并申请解锁权限. 等 ...

  3. Centos7防火墙常用命令

    有些人安装的linux的系统默认防火墙不是iptables,而是firewall,那就得使用以下方式关闭防火墙了. >>>关闭防火墙 systemctl stop firewalld ...

  4. CentOS7 SSH 密码正确,但仍提示“Permission denied”

    我看其他人解决办法,有的是防火墙端口,有的是sshd_config文件的密码登录,有的ip冲突等等,我都按照那些修改了,但是都不通,最后修改了这个,好用了. 看一下SElinux,敲sestatus, ...

  5. 【串线篇】Mybatis缓存之一级缓存

    1.体会 一级缓存:MyBatis:SqlSesion级别的缓存:默认存在,不需要设置. 机制:只要之前查询过的数据,mybatis就会保存在一个缓存中(Map):下次获取直接从缓存中拿:当前sess ...

  6. Java EE会话技术Cookie和Session

    会话技术 一.定义 会话技术是帮助服务器记住客户端状态的(区分客户端的).将客户访问的信息存在本地的叫Cookie技术,存在服务器上的叫Session技术. 注意: 一次会话何时开始?从打开一个浏览器 ...

  7. word里输入英文字母间距变宽,字体改变,怎么回事?

    word里输入英文字母间距变宽,字体改变,怎么回事? 你有没有遇到下面这种情况,在word里输入英文,变的很奇怪,就像下面图中那样: 是不是很蛋疼?看起来很别扭. 那是因为输入法是全角状态 我们只要把 ...

  8. mssql 动态表名,游标

    ALTER PROCEDURE [dbo].[ken_overtime_check](@p_use_code nvarchar(100),@p_table_name nvarchar(1000)) A ...

  9. Echarts--Y坐标标题显示不全

    如:下图,Y坐标标题显示不全 y2可以控制不显示区域的高度,就能显示全啦 grid:{ x:40, x2:100, y2:200 }

  10. [原创] Delphi 修改新建窗体时候的默认字体格式

    Delphi 修改新建窗体时候的默认字体格式 操作步骤: 1.运行输入“regedit” 2.找到目录(这里默认以Delphi 7为例) HKEY_CURRENT_USER\Software\Borl ...