c++primer,自定义一个复数类
#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,自定义一个复数类的更多相关文章
- C++ 实验 使用重载运算符实现一个复数类
实验目的: 1.掌握用成员函数重载运算符的方法 2.掌握用友元函数重载运算符的方法 实验要求: 1.定义一个复数类,描述一些必须的成员函数,如:构造函数,析构函数,赋值函数,返回数据成员值的函数等. ...
- JavaScript实现一个复数类
<script type="text/javascript"> /** * 这里定义Complex类,用来描述复数 */ /** * 这个构造函数为它所创建的每个实例定 ...
- Java自定义一个字典类(Dictionary)
标准Java库只包含Dictionary的一个变种,名为:Hashtable.(散列表) Java的散列表具有与AssocArray相同的接口(因为两者都是从Dictionary继承来的).但有一个方 ...
- java中自定义一个异常类 在某些情况抛出自定的异常 ----------阻断程序
//=============定义异常类 package org.springblade.flow.engine.errorException; /** * 自定义异常处理写入sap失败 */ pub ...
- Python自定义一个数组类,支持数组之间的四则运算和其他常见方法
class MyArray: '''保证输入的内容是整型.浮点型''' def ___isNumber(self, num): if not isinstance(num, (int,float)): ...
- 定义一个复数类Complex
#include<iostream> #include<math.h> using namespace std; class Complex{ public: Complex( ...
- 复数类(C++练习一)
写一个复数类,实现基本的运算,目的熟悉封装与数据抽象. 类的定义 #include <iostream> #include <vector> using namespace s ...
- 安卓开发37:自定义的HorizontalScrollView类,使其pageScroll的时候焦点不选中
自定义一个HorizontalScrollView类,主要为了让这个HorizontalScrollView不能鼠标点击,不能左右按键,并且没有焦点. public class ImageMoveHo ...
- C++习题 复数类--重载运算符2+
Description 定义一个复数类Complex,重载运算符"+",使之能用于复数的加法运算.参加运算的两个运算量可以都是类对象,也可以其中有一个是整数,顺序任意.例如,c1+ ...
随机推荐
- Linux终端下简单的登录程序 密码不回显
在Linux进行登录是输入密码不会被回显,所以我也写了个简单的登入程序,使得在输入密码时不再进行回显. #include <stdio.h> #include <stdlib.h&g ...
- android 学习路线
转载来源:https://blog.csdn.net/lixuce1234/article/details/77947405 jixiaohua发了一篇一个老鸟也发了一份他给公司内部小伙伴整理的路线图 ...
- Python之文件路径名的操作
使用 os.path 模块中的函数来操作路径名 import os # 获取当前文件路径 path=os.path.abspath(__file__) # 获取绝对路径 /home/zzy/Pycha ...
- 20191114PHP图像绘制
<?phpob_clean();$img=imagecreate(400,400);$back=imagecolorallocate($img,200,200,100); $blue=image ...
- js中的对象类型的基本操作
示例 /** * 对象属于一种复合数据类型,在对象中可以保存多个不同数据类型的属性 * 对象的分类: * 1.内建对象 * - 由ES标准定义的对象,在任何ES的实现中都可以使用,比如:Math, * ...
- JSON对象与JavaScript对象的区别
//js对象的字面量表示法: var people1={ name:'hehe', age:18 }; //json的格式是: var people1={ "name":'hehe ...
- vue.js(6)--v-model
v-model实现数据的双向绑定(简易计算器实例) 简易计算器实例 <!DOCTYPE html> <html lang="en"> <head> ...
- 二、Ajax请求MVC中数据查询表返回datatable
一.Ajax请求MVC中数据查询表返回datatable 解决方式 返回list
- Codeforces Round #393 (Div. 2) - A
题目链接:http://codeforces.com/contest/760/problem/A 题意:给定一个2017年的月份和该月的第一天的星期,问该月份的日历表中需要多少列.行有7列表示星期一~ ...
- Kotlin——关于字符串(String)常用操作汇总
在前面讲解Kotlin数据类型的时候,提到了字符串类型,当然关于其定义在前面的章节中已经讲解过了.对Kotlin中的数据类型不清楚的同学.请参考Kotlin——初级篇(三):数据类型详解这篇文章. 在 ...