c++入门之 再话类
对于类,其结构并不难,但要理解其设计思想也并不容易,在此,我们可以通过下面的代码进一步理解和使用类:
# ifndef VECTOR_H_
# define VECTOR_H_
# include "iostream" namespace VECTOR //注意,这里对这个类定义了名称空间,实际上,在写自己的类时,也应该定义自己的名称空间
{
class Vector
{
public:
enum Mode{RECT,POL};//因为这个量需要用户自己去设定
private: //注意:私有成员(无论是函数还是变量)只能被类内部成员访问
double x;
double y;
double mag;
double ang;
Mode mode; void set_mag();
void set_ang();
void set_x();
void set_y(); //体会将这些函数放在这里的用意!!
public: //共有成员可以被所有访问!!理解这个意思
Vector();//构造函数
Vector(double n1,double n2,Mode form = RECT);//注意,这里有默认参数
void reset(double n1, double n2, Mode form = RECT);
~Vector();//析构函数
double xval() const{ return x; }
double yval() const{ return y; }
double magval() const{ return mag; }
double angval() const{ return ang; }
void polar_mode();
void rect_mode(); Vector operator+(const Vector &b) const;
Vector operator-(const Vector &b) const;
Vector operator-() const;
Vector operator*(double n) const; friend Vector operator*(double n, const Vector &a);//注意这里采用了友元函数的做法,应该显示包含所有参数
friend std::ostream & operator<<(std::ostream &os, const Vector & v);//昨天没有思考返回引用是否存在问题???因为局部变量被销毁的问题
}; }
# endif
该类定义中:除了备注的一些以外,总结这么几点:
1 定义了一个类的时候,限定了该类的名称空间通常是一件好事,以免自己的变量和别人的发生了冲突
2 公有还是私有并无界限之分,完全取决于程序的功能。
3 我们通常会发现:当定义一个类成员函数时,通常需要:构造函数,析构函数,甚至友元函数
4 私有成员(无论是变量还是函数)只能被类内部的成员进行访问,而共有成员 可以被其他类甚至其他任何东西访问。究其本质:公有部分 是提供的接口
下面给出该定义:
# include"cmath" //从下文的调用方法来看,这里应该是函数库,而不是类库
# include "vector.h"
using std::sqrt; //注意 std 包含了很多
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout; namespace VECTOR //名称空间的意义是很有必要的
{
const double Rad_to_deg = 45.0 / atan(1.0);
void Vector::set_ang()
{
mag = sqrt(x*x + y*y); //求极长
} void Vector::set_ang()
{
if (x == 0.0 && y == 0.0)
ang = 0.0;
else
ang = atan2(y, x);//求极角
} void Vector::set_x() //这些是私有函数
{
x = mag*cos(ang);//私有函数可以访问私有变量表明私有成员也可以相互访问
} void Vector::set_y()
{
y = mag*sin(ang);
} Vector::Vector()
{
x = y = mag = ang = 0.0;
mode = RECT;
} Vector::Vector(double n1, double n2, Mode form)
{
mode = form;
if (form == RECT)
{
x = n1;
y = n2;
set_mag();//访问了私有成员
set_ang();//体会这里的设计思想
}
else if (form == POL)
{
mag = n1;
ang = n2;
set_x();
set_y();
}
else
{
cout << "Incorrect 3rd argument to Vector()--";
cout << "vector set to 0\n";
x = y = mag = ang = 0.0;
mode =RECT;
}
}
void Vector::reset(double n1, double n2, Mode form)
{
mode = form;
if (form = RECT)
{
x = n1;
y = n2;
set_mag();
set_ang();
}
else if (form = POL)
{
mag = n1;
ang= n2;
set_x();
set_y();
}
else
{
cout << "Incorrect 3rd argument to Vector()--";
cout << "vector set to 0\n";
x = y = mag = ang = 0.0;
mode = RECT;
}
}
Vector::~Vector()//
{ } void Vector::polar_mode()
{
mode = POL;
} void Vector::rect_mode()
{
mode = RECT;
} Vector Vector::operator+(const Vector &b) const
{
return Vector(x + b.x, y + b.y);
} Vector Vector::operator-(const Vector &b) const
{
return Vector(x - b.x, y - b.y);
} Vector Vector::operator-() const
{
return Vector(-x, -y);
}
Vector Vector::operator*(double n) const
{
return(n*x,x*y)
} Vector operator*(double n, const Vector & a)
{
return a*n; //注意,虽然这里进行了返回,但并没有结束,而是继续调用了成员函数,
} std::ostream & operator<<(std::ostream & os, const Vector & v)
{
if (v.mode == Vector::RECT)
os << "(x,y) = (" << v.x << "," << v.y << ")";
else if (v.mode == Vector::POL)
{
os << "(m,a) = (" << v.mag << "," << v.ang + Rad_to_deg << ")";
}
else
os << "Vector object mode is invalid";
}
}
1. 我们注意107行和112行的代码:本质上,进行了加法和减法之后,得到的是一个新的类对象,但由于这个类对象不止一种表示形式(直角坐标和极坐标),这里巧妙的利用了 返回构造函数的执行。这告诉我们:构造函数并不仅仅用于初始化,构造函数的本意:构造新的对象,一定要认识这一本质特征和思想。
2 我们注意124行的代码:return a*n; 本质上,对象乘以一个数无法实现,但这里,其实,并没有返回,而是回去重新调用了上面的*。
3 注意:129行和131行:if (v.mode == Vector::RECT)。为何要加Vector::RECT而不是RECT,这是因为:
友元函数虽然在public中,但友元函数并不在类作用域中!!! 这对于所有友元函数都成立!!!
c++入门之 再话类的更多相关文章
- c++入门之再话内存和引用
此处没有代码,仅仅讨论一些这样的问题:我们为何使用引用?在哪里使用引用? 首先从函数的角度思考?:函数进行一般参数传递的时候,是怎么样传递的?普通类型的参数传递,是将传递的实参复制一份,到另一个内存空 ...
- c++入门之再话命名空间的意义
c++中使用了命名空间这一概念,通过下面这个代码,我们将深刻认识到命名空间的重要作用和意义: # include"iostream" using namespace std; na ...
- JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式
相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...
- Python编程从入门到实践笔记——类
Python编程从入门到实践笔记——类 #coding=gbk #Python编程从入门到实践笔记——类 #9.1创建和使用类 #1.创建Dog类 class Dog():#类名首字母大写 " ...
- python入门学习:8.类
python入门学习:8.类 关键点:类 8.1 创建和使用类8.2 使用类和实例8.3 继承8.4 导入类 8.1 创建和使用类 面向对象编程是最有效的软件编写方法之一.在面向对象编程中,你编写 ...
- Node.js开发入门—HelloWorld再分析
在Node.js开发入门(1)我们用http模块实现了一个简单的HelloWorld站点,这次我们再来细致分析下代码.了解很多其它的细节. 先看看http版本号的HelloWorld代码: 代码就是这 ...
- Python 3 快速入门 3 —— 模块与类
本文假设你已经有一门面向对象编程语言基础,如Java等,且希望快速了解并使用Python语言.本文对重点语法和数据结构以及用法进行详细说明,同时对一些难以理解的点进行了图解,以便大家快速入门.一些较偏 ...
- 【PHP面向对象(OOP)编程入门教程】11.类的继承
继承作为面向对象的三个重要特性的一个方面,在面向对象的领域有着及其重要的作用,好像没听说哪个面向对象的语言不支持继承. 继承是PHP5面象对象程序设计的重要特性之一,它是指建立一个新的派生类,从一个或 ...
- Java+7入门经典 - 6 扩展类与继承 Part 1/2
第6章 扩展类与继承 面向对象编程的一个重要特性: 允许基于已定义的类创建新的类; 6.1 使用已有的类 派生 derivation, 派生类 derived class, 直接子类 direct s ...
随机推荐
- 验证对Random的两个猜想
猜想1:Random.Next()产生的随机数不会有重复. 猜想2:大量级执行Random.Next(int i)分布在各个数值上的概率是均匀的. 验证猜想1 /*如果Random.Next()产生的 ...
- TNS-12535: TNS:operation timed out
AWS数据库云服务器出现了连接超时的错误,于是查看相关时段的alert日志,发现了如下的错误: **************************************************** ...
- MySQL高性能优化实战总结!
1.1 前言 MySQL对于很多Linux从业者而言,是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰.在进行MySQL的优化之前必须要了解的就是MySQL的查询过程,很多 ...
- 【PAT】B1009 说反话
在输入时直接分别将每个单词放入字符串,逆序输出字符串数组 #include<stdio.h> int main(){ int num=0; char ans[90][90]; while( ...
- Servlet(六):连接数据库,完整的CRUD
Servlet的知识点大致讲完了,今天补充下与之相关的一些小知识,然后做一个完整的小例子. 一.MVC设计模式 1.MVC设计模式是什么? 在了解MVC之前,先聊聊Model1.Model2开发模式. ...
- reportComplaints.js: Uncaught TypeError: Cannot read property 'message' of undefined
vonic 中遇到这么个问题, 一直提示我未定义, 可是明明有定义 var tab={ message:{ number:'', title:'' } } var id= { template: '# ...
- python while and for
一.while循环 1.格式: while 条件: while循环体 else: 循环正常跳出执行的语句 2.实例: index= : : break #直接跳出while ,不会执行else els ...
- Eclipse debug 断点不能调试 ,Eclipse Unable to install breakpoint in 解决办法
解决:[1]项目工程名 ,右键 --> properties --> java compiler -->class file Generation 位置 Add line numb ...
- (转)Spring Boot(十二):Spring Boot 如何测试打包部署
http://www.ityouknow.com/springboot/2017/05/09/spring-boot-deploy.html 有很多网友会时不时的问我, Spring Boot 项目如 ...
- JavaScript的对象详解
JavaScript对象的概述 什么是对象,代表现实中的某个事物, 是该事物在编程中的抽象,多个数据的集合体(封装体),用于保存多个数据的容器 为什么要用对象,便于对多个数据进行统一管理 对象属于一种 ...