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

 # 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. SQLOS任务调度算法

    前些天在处理一个SQL Server LATCH导致的数据库停止响应问题时,遇到了一些需要SQLOS调度知识解决的问题,正好以前看过一篇官网的文章,在这里稍作修改贴出来. 原文网址如下: https: ...

  2. 【PAT】B1007 素数对猜想

    素数筛筛出规定范围内的所有素数存入数组 遍历数组,如果满足于后边的差2,计数器加加 #include <cstdio> const int maxn = 10000001; int pri ...

  3. Spring容器技术内幕之BeanWrapper类介绍

    引言 org.springframework.beans.BeanWrapper是Spring框架中重要的组件类.BeanWrapper相当于一个代理器,Spring委托BeanWrapperwanc ...

  4. Spring的jdbc模板2:使用开源的连接池

    上篇简要介绍了如何在spring中配置默认的连接池和jdbc模板,这篇来介绍开源的连接池配置与属性引入 C3P0连接池配置: 引入jar包 配置c3p0连接池 <?xml version=&qu ...

  5. MySQL高级知识(十一)——Show Profile

    前言:Show Profile是mysql提供的可以用来分析当前会话中sql语句执行的资源消耗情况的工具,可用于sql调优的测量.默认情况下处于关闭状态,并保存最近15次的运行结果. 1.分析步骤 # ...

  6. Spring+SpringMVC+Mybatis环境的搭建(使用Intellij IDEA)

    前言:本文主要介绍利用IDEA如何搭建SSM环境,并使用mybatis的逆向生成功能,根据数据表生成对应mapper接口和sql映射文件.具体步骤如下. 开发环境: IDEA 14.1.7 maven ...

  7. 【SDOI2014】向量集

    [SDOI2014]向量集 题目描述 我们分析一波: 假设我们询问\((A,B)\),\(x_i>x_j\)若 \[ A\cdot x_i+B\cdot y_i>A\cdot x_j+B\ ...

  8. C#语言のC#扩展方法(.Net特性)

    this在C#中的常见用法:1.在C#中,this关键字代表当前实例,我们可以用this.来调用当前实例的成员方法,变量,属性,字段等; 2.也可以用this来做为参数状当前实例做为参数传入方法. 3 ...

  9. Linux之初识磁盘

    磁盘知识体系概括 机械硬盘和固态硬盘 机械磁盘剖开图 磁盘工作的视频动画,主轴转动,机械手读写 模拟磁盘工作视频,点击中间三角播放 磁盘结构详解 磁盘外部结构 组成 主要由三部分组成:盘片.主轴(机械 ...

  10. SQLite也可能出现死锁

    提到锁就不得不说到死锁的问题,而SQLite也可能出现死锁.下面举个例子:连接1:BEGIN (UNLOCKED)连接1:SELECT ... (SHARED)连接1:INSERT ... (RESE ...