对于类,其结构并不难,但要理解其设计思想也并不容易,在此,我们可以通过下面的代码进一步理解和使用类:

 # 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++入门之 再话类的更多相关文章

  1. c++入门之再话内存和引用

    此处没有代码,仅仅讨论一些这样的问题:我们为何使用引用?在哪里使用引用? 首先从函数的角度思考?:函数进行一般参数传递的时候,是怎么样传递的?普通类型的参数传递,是将传递的实参复制一份,到另一个内存空 ...

  2. c++入门之再话命名空间的意义

    c++中使用了命名空间这一概念,通过下面这个代码,我们将深刻认识到命名空间的重要作用和意义: # include"iostream" using namespace std; na ...

  3. JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式

    相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...

  4. Python编程从入门到实践笔记——类

    Python编程从入门到实践笔记——类 #coding=gbk #Python编程从入门到实践笔记——类 #9.1创建和使用类 #1.创建Dog类 class Dog():#类名首字母大写 " ...

  5. python入门学习:8.类

    python入门学习:8.类 关键点:类 8.1 创建和使用类8.2 使用类和实例8.3 继承8.4 导入类 8.1 创建和使用类   面向对象编程是最有效的软件编写方法之一.在面向对象编程中,你编写 ...

  6. Node.js开发入门—HelloWorld再分析

    在Node.js开发入门(1)我们用http模块实现了一个简单的HelloWorld站点,这次我们再来细致分析下代码.了解很多其它的细节. 先看看http版本号的HelloWorld代码: 代码就是这 ...

  7. Python 3 快速入门 3 —— 模块与类

    本文假设你已经有一门面向对象编程语言基础,如Java等,且希望快速了解并使用Python语言.本文对重点语法和数据结构以及用法进行详细说明,同时对一些难以理解的点进行了图解,以便大家快速入门.一些较偏 ...

  8. 【PHP面向对象(OOP)编程入门教程】11.类的继承

    继承作为面向对象的三个重要特性的一个方面,在面向对象的领域有着及其重要的作用,好像没听说哪个面向对象的语言不支持继承. 继承是PHP5面象对象程序设计的重要特性之一,它是指建立一个新的派生类,从一个或 ...

  9. Java+7入门经典 - 6 扩展类与继承 Part 1/2

    第6章 扩展类与继承 面向对象编程的一个重要特性: 允许基于已定义的类创建新的类; 6.1 使用已有的类 派生 derivation, 派生类 derived class, 直接子类 direct s ...

随机推荐

  1. 洗礼灵魂,修炼python(81)--全栈项目实战篇(9)—— 购物商城登录验证系统

    都在线购物过吧?那么你应该体验过,当没有登录账户时,点开购物车,个人中心,收藏物品等的操作时,都会直接跳转到登录账户的界面,然后如果登录一次后就不用再登录,直到用户登出. 是的,本次项目就是做一个登录 ...

  2. shell编程 学好内功(一)

    shell 背景 什么是shell编程 高大上的解释,往往让人摸不住头脑.一句话概括就是:shell编程就是对一堆Linux命令的逻辑化处理. 为什么要会shell编程 举个简单的例子,我们做java ...

  3. tomcat启动超过时间

    Server Tomcat v9.0 Server at localhost was unable to start within 45 seconds. 运行超时 最近我切换了JDK版本之后,将10 ...

  4. python的shelve模块

    shelve shelve是一额简单的数据存储方案,他只有一个函数就是open(),这个函数接收一个参数就是文件名,并且文件名必须是.bat类型的.然后返回一个shelf对象,你可以用他来存储东西,就 ...

  5. Python 进程管理工具 Supervisor 使用教程

    Supervisor 是基于 Python 的进程管理工具,只能运行在 Unix-Like 的系统上,也就是无法运行在 Windows 上.Supervisor 官方版目前只能运行在 Python 2 ...

  6. props default 数组/对象的默认值应当由一个工厂函数返回

    export default {props: { slides:{ type:Array, default:[] } },这是我的代码 报错是Invalid default value for pro ...

  7. (转)Geoserver基础配图研究

    https://blog.csdn.net/zbcx_ZGIS/article/details/82216151 1面图层配图 1.1基本框架 这个是geoserver默认的polygon的代码,我们 ...

  8. (转)springcloud(一):大话Spring Cloud

    http://www.ityouknow.com/springcloud/2017/05/01/simple-springcloud.html 研究了一段时间Spring Boot了准备向Spring ...

  9. Java 8 新特性:3-函数(Function)接口

    (原) 以前,在创建泛型时,是这么写的: List<String> list = new ArrayList<String>(); 现在,可以这么写了: List<Str ...

  10. CentOS 7 安装telnet服务

    今天测试zabbix需要用到telnet服务,查询到Centos7下下载安装telnet服务的方法,特此整理记录! 一.通过yum下载安装telnet yum -y install xinetd te ...