码迷,mamicode.com
首页 > 其他好文 > 详细

大作业的个人总结(一)

时间:2016-01-10 14:20:01      阅读:538      评论:0      收藏:0      [点我收藏+]

标签:

在写代码的时候,中间遇到了一些问题,后来查阅了一些书籍,并且在网上找了一些相关知识,以下遇到的问题和解决方案。

 

刚开始写的时候,代码打算按照头文件和源文件分开的形式来写,但是来回使用#include就会造成类成员函数的重载定义。

如果a.h中含有类A的定义,b.h中含有类B的定 义,由于类B的定义依赖了类A,所以b.h中也#include了a.h。现在有一个源文件,它同时用到了类A和类B,于是程序员在这个源文件中既把 a.h包含进来了,也把b.h包含进来了。这时,问题就来了:类A的定义在这个源文件中出现了两次!于是整个程序就不能通过编译了。

使用"#define"配合条件编译可以很好地解决这个问题。在一 个头文件中,通过#define定义一个名字,并且通过条件编译#ifndef...#endif使得编译器可以根据这个名字是否被定义,再决定要不要继 续编译该头文中后续的内容。

故在每个头文件的开头均有:

#ifndef A
#define A
//XX.h
#endif


另外,在Frame,Robot等类中数据成员含有其他类的对象,这样在定义构造函数时,要初始化对象,同时也要定义拷贝构造函数,这样才能定义返回该类对象的函数。

因为在函数的调用过程中,要用到类的拷贝构造函数。

如下:

Box f()
{   Box box1(12,15,18);
     return box1;   
}
int main()
{    Box box2;
      box2=f();
}

由于box1是在函数f中定义的,在调用f函数结束后,box1的生命周期就结束了,因此并不是将box1带回main函数,而是在函数f结束前执行return 语句时,调用Box类中的复制构造函数,按照box1复制一个新的对象,然后将它赋值给box2。

例如在Slover.h文件中,声明了两个Solver类的成员函数

JointFrame ToJoint(Point &);
Point JointTo(JointFrame &);

这样,在函数返回的时候要调用复制构造函数,若Point和JointFrame类中有对象的话,就需要自己定义拷贝构造函数,而不能使用默认的拷贝构造函数。

如下是一段程序来表示如何来定义类的构造函数和拷贝构造函数:

#include<iostream>
#include<cmath>
using namespace std;
class Point
{
 public :
  Point(int xx=0,int yy=0){X=xx;Y=yy;}
  Point(Point &p);
  int GetX()  {return X;}
  int GetY()   {return Y;}
private:
  int X,Y;
};
Point::Point(Point &p)             //拷贝函数的实现
{
 X=p.X;
 Y=p.Y;
 cout<<"Point拷贝函数被调用"<<endl;
}
//类的组合
class Line 
{
public:
 Line(Point xp1,Point xp2);
 Line(Line &);
 double GetLen(){return len;}
private:
 Point p1,p2;
 double len;
};
//组合类的构造函数
Line::Line(Point xp1,Point xp2)
:p1(xp1),p2(xp2)
{
 cout<<"Line构造函数被调用"<<endl;
 double x=double(p1.GetX()-p2.GetX());
 double y=double(p1.GetX()-p2.GetY());
 len=sqrt(x*x+y*y);
}
//组合类的拷贝构造函数
Line::Line(Line &L):p1(L.p1),p2(L.p2)
{
 cout<<"Line 拷贝构造函数被调用"<<endl;
 len=L.len;
}
//主函数
int main()
{
 Point myp1(1,1),myp2(4,5);             //建立Point类的对象
 Line line(myp1,myp2);                  //建立Line类的对象
 Line line2(line);                      //利用拷贝构造函数建立一个新对象
 cout<<"The length of the line is :";
 cout<<line.GetLen()<<endl;
 cout<<"The length of the line2 is :";
 cout<<line2.GetLen()<<endl;

 

另外,由于使用Eigen,所以在进行计算时,可以充分利用其函数:

//
Vector2d a(5.0, 6.0); 
//
Matrix2d m;
m << 1, 2, 3,  
4, 5, 6;

Eigen提供+、-、一元操作符“-”、+=、-=,例如:

二元操作符+/-表示两矩阵相加(矩阵中对应元素相加/,返回一个临时矩阵): B+C 或 B-C;

一元操作符-表示对矩阵取负(矩阵中对应元素取负,返回一个临时矩阵): -C; 

组合操作法+=或者-=表示(对应每隔元素都做相应操作):A += B 或者 A-=B

另外,矩阵还提供与标量(单一个数字)的乘除操作,表示每个元素都与该标量进行乘除操作。例如:

二元操作符*在:A*a中表示矩阵A中的每隔元素都与数字a相乘,结果放在一个临时矩阵中,矩阵的值不会改变。

对于a*A、A/a、A*=a、A /=a也是一样,例如下面的代码:

 

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
Matrix2d a;
a << 1, 2,
3, 4;
Vector3d v(1,2,3);
std::cout << "a * 2.5 =\n" << a * 2.5 << std::endl;
std::cout << "0.1 * v =\n" << 0.1 * v << std::endl;
std::cout << "Doing v *= 2;" << std::endl;
v *= 2;
std::cout << "Now v =\n" << v << std::endl;
}

 

矩阵的相乘,矩阵与向量的相乘也是使用操作符*,共有*和*=两种操作符,其用法可以参考如下代码:

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
Matrix2d mat;
mat << 1, 2,
3, 4;
Vector2d u(-1,1), v(2,0);
std::cout << "Here is mat*mat:\n" << mat*mat << std::endl;
std::cout << "Here is mat*u:\n" << mat*u << std::endl;
std::cout << "Here is u^T*mat:\n" << u.transpose()*mat << std::endl;
std::cout << "Here is u^T*v:\n" << u.transpose()*v << std::endl;
std::cout << "Here is u*v^T:\n" << u*v.transpose() << std::endl;
std::cout << "Let‘s multiply mat by itself" << std::endl;
mat = mat*mat;
std::cout << "Now mat is mat:\n" << mat << std::endl;
}

 

因此,可以利用:

Vector m ;
m.transpose()*m;

这样便可求得向量模的平方,但是在对向量单位化的时候,不能使用:

m /= sqrt(m.transpose()*m);

这是因为:

//If you want to replace a matrix by its own transpose, do NOT do this:
m = m.transpose(); // bug!!! caused by aliasing effect

//Instead, use the transposeInPlace() method:
m.transposeInPlace();

//which gives Eigen good opportunities for optimization, or alternatively you can also do:
 m = m.transpose().eval();

 


 

大作业的个人总结(一)

标签:

原文地址:http://www.cnblogs.com/zhibos/p/5118200.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!