12.4总结-创新互联

1、Link Error 和 Compile Error

1) Link阶段发生的错误(文件本身complie没有问题,但是互相链接阶段的问题。例如声明了函数但是没有找到主体、库文件的错误以及互相引用的问题等。)

创新互联专注于资中企业网站建设,响应式网站开发,商城网站建设。资中网站建设公司,为资中等地区提供建站服务。全流程按需搭建网站,专业设计,全程项目跟踪,创新互联专业和态度为您提供的服务

*error以LNK开头
在这里插入图片描述

2) Complie阶段的问题。(某个文件本身的问题,可能是语法等)

error以C开头
在这里插入图片描述

2、头文件中函数定义:使用inline 或者 static

#include相当于复制过去,如果在一个头文件A.h中定义函数B,其他多个文件都使用了#include"A.h",那B函数就会出现多次定义的LNK错误。(always have a body in xx,but… )

解决办法:
1)只在头文件中写函数声明,函数body写入其他函数。
2)在函数前加static,相当于该函数为本文件私有使用,不对外可见。所有使用该函数的文件相当于都单独拥有一份该函数的内部定义。
3)在函数前加inline,内联函数相当于直接在函数引用中替换值。

3、Inline 内联函数
  1. 隐式内联、显式内联
    定义在类内的函数都是隐式内联函数,显示内联需要增加关键字inline

参考:隐式内联函数和显式内联函数

**隐式内联**

using namespace std;

class A

{public:

    void func(int x,int y){i=x;j=y;}     //成员函数func()是内联函数

    void print(){cout<<"两数相乘为:"<A a;

    a.func(1,2); //调用func(1,2)内联函数等于直接将i=1,j=2写在这里

    a.print(); //调用print()内联函数等于将"cout<<"两数相乘为:"<

2)不是所有的函数都适合定义为inline,因为inline是以代码复制、即增加内存消耗为代价换取代码运行速度的(无需调用函数而是直接复制替换)。
①使用次数过多的,每次都复制,内存消耗量++
②本身inline函数中消耗就较大的,不适合。比如当内部有循环体时,执行函数体的循环要比调用函数的花销更大。

参考:inline那些事

4、C++类型转换及其!!极其!!不智能

一定要注意数据类型不同时的转换丢失情况。bool 、int、float、double它是一点不会转!!!
另外,注意output里面warning的信息,很可能就是最后导致error的地方!没报错是因为语法上对,逻辑上和实际严格检查上不一定对。
在这里插入图片描述

编译器报错的滞后性:

很可能报错在n行,实际出错在n-1行,报错位置比真正出错的位置滞后一行。
例如:在第7行缺少分号,但在编译第8行时才会发现第7行有错,因此报错在8行。记得debug时检查上一行内容。

5、判断点是否在三角形内部 法1:一般程序都用同侧法,即将三角形三边看作有方向的AB、BC、CA,看Q点是否在三条边的同侧。

图1
新的问题,如何判断两个点在一条线的同侧?——右手螺旋定则!
在这里插入图片描述
根据向量的叉乘以及右手螺旋定则,ABxAM (x表示叉乘,这里向量省略了字母上面的箭头符号)的方向为向外指出屏幕,ABxAN也是向外指出屏幕,但ABxAO的方向是向内指向屏幕,因此M,N在直线AB的同侧,M ,O在直线AB的两侧。实际计算时,只需要考虑叉积的数值正负。
假设以上各点坐标为A(0,0), B(4,0), M(1,2), N(3,4), O(3,-4), 则:

ABxAM = (4,0)x(1,2) = 42 - 01 = 8

ABxAN = (4,0)x(3,4) = 44 – 03 = 16

ABxAO = (4,0)x(3,-4) = 4*-4 – 0*3 = –16

回到三角形内外的判断中来,以Q点图为例。判断Q点:
flag1=ABxAQ
flag2=BCxBQ
flag3=CAxCQ
3个flag同号则在内部,异号则在外部。

PS:点乘(意义是cos)可以用于判断角度是否大于90°,大于为负,小于为正

//ours_1
static bool insideTriangle(int x, int y, const Vector3f* _v)
{// TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]                          
    
    //p
    Eigen::Vector3f v0p = {_v[0].x() - x,_v[0].y() - y,1.0f };
    Eigen::Vector3f v1p = {_v[1].x() - x,_v[1].y() - y,1.0f };
    Eigen::Vector3f v2p = {_v[2].x() - x,_v[2].y() - y,1.0f };
    //v
    Eigen::Vector3f v0v1 = {_v[0].x() - _v[1].x(),_v[0].y() - _v[1].y(),1.0f };
    Eigen::Vector3f v1v2 = {_v[1].x() - _v[2].x(),_v[1].y() - _v[2].y(),1.0f };
    Eigen::Vector3f v2v0 = {_v[2].x() - _v[0].x(),_v[2].y() - _v[0].y(),1.0f };

    float flagv0v1 = v0p.cross(-v2v0).z();
    float flagv1v2 = v1p.cross(-v0v1).z();
    float flagv2v0 = v2p.cross(-v1v2).z();

    if (flagv0v1>0) {return  flagv1v2>0 && flagv2v0>0;
    }
    else {  
        return flagv1v2<0 && flagv2v0<0;
    }
        
}
法2:自向量乘法,其实跟上一个方法的核心思想一样,但是计算量小,中间变量也更小

flag1=QAxQB
flag2=QBxQC
flag3=QCxQA
同号内部,异号外部

static bool insideTriangle(int x, int y, const Vector3f* _v){Eigen::Vector3f pv0 = {x - _v[0].x() ,y- _v[0].y() ,1.0f };
    Eigen::Vector3f pv1 = {x - _v[1].x() ,y - _v[1].y() ,1.0f };
    Eigen::Vector3f pv2 = {x - _v[2].x() ,y - _v[2].y() ,1.0f };

    if (pv0.cross(pv1).z()>0 ) {return  pv1.cross(pv2).z() >0 && pv2.cross(pv0).z() >0;
    }
    else {return pv1.cross(pv2).z()< 0 && pv2.cross(pv0).z()< 0;
    }

}

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


文章标题:12.4总结-创新互联
URL链接:http://hbruida.cn/article/dhsije.html