ROS学习笔记5:C++基础知识

前言:

        作为一名机械专业学生,在没有C++基础的情况下,直接网上的代码资源学习ROS收获不大。虽然老师们并不要求我们会写相关代码,但能看懂代码段的含义是非常必要的,因此在正式开始ROS学习应用前需要对C++有基本概念。

一、C++介绍:

1.面向过程程序设计的缺点:

(1)可读性不佳:在面向过程的程序设计中,函数及其所操作的数据结构没有直观的联系,导致随着程序规模的增加可读性下降。

(2)扩展性差:面向过程程序设计没有“封装”和“隐藏”的概念,要访问某个数据结构中的某个变量可以直接访问,但要修改该变量时需要将所有访问该变量的语句都找出来修改,且难以差错和重用代码。

2.C++的特点:

        C++是C语言的继承,既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。

二、类和对象:

1.介绍类和对象:

(1)面向对象编程:

        面向对象是相对于面向过程来讲的,面向对象思想是把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模。

        面向对象有三大特性:封装、继承和多态。

        C++中的类是实现面向对象编程的核心要素。

(2)类的介绍:

        类是根据客观事物抽象而成,形成一类事物;然后用类去定义对象,形成这类事物的具体个体;类把属性和方法进行封装,同时对类的属性和方法进行访问控制。

        下面举例圆类说明:

1)代码段:

//要使用C++输入输出工具,要提供这两行代码 
#include      //包含输入输出函数的头文件 
using namespace std;    //释放std命名空间中的变量名,函数名以及类型名

//声明常量PI=3.14 
const double PI=3.14;

class Circle
{
public: //访问权限:公共的权限

    //属性
	double R;//半径
	
	//方法
	
	//获取圆的周长
	double cal_zc()
	{
		return 2*PI*R;
	}
	
	//获取圆的面积
	double cal_mj()
	{
		return PI*R*R;
	}
};

int main()
{
	//创建对象
	Circle c;                               //声明类的对象
	c.R=10;                                 //创建对象
	cout<<"半径为:"<

2)结果:

ROS学习笔记5:C++基础知识_第1张图片

3)解释代码: 

        ①Circle是一个类,其中封装了一些方法:

一个属性:R

两个方法:cal_zc()和cal_mj(),分别计算圆的周长和面积

        ②public规定了类中的内容的访问权限。(访问权限有public,private和protected)

public:公有成员,可以在任何地方访问。

private:私有成员,只能在类内部访问。

protected:保护成员,可以在类内部或子类内部访问。

        ③main函数:

int main()
{
	//创建对象
	Circle c;                               //声明类的对象
	c.R=10;                                 //创建对象
	cout<<"半径为:"<

        对象是根据类来创建的,声明类的对象就像声明基本类型的变量一样。

        Circle类的公共成员可以直接被对象用''访问。

        c.R访问了公共成员属性半径。

        c.cal_zc和c.cal_mj访问了两个公共成员函数,分别计算了周长和面积。

(3)类包含的四个要素:

classname
{
    access specifiers//访问修饰符:public/private/protected
        date members/variables;//变量
        member fuctions(){}//方法
};//分号结束一个类

1)类名classname

2)访问修饰符access specifiers

public:公有成员,可以在任何地方访问。

private:私有成员,只能在类内部访问。

protected:保护成员,可以在类内部或子类内部访问。

3)属性

4)方法

        成员函数也可以类内声明,类外实现。注意,在类外实现时需要加上Circle::来指定作用域,表示实现的是Circle类中的成员函数。

class Circle
{
public: //访问权限:公共的权限

    //属性
	double R;//半径
	
	//方法
	
	//获取圆的周长
	double cal_zc();
	
	//获取圆的面积
	double cal_mj();

};


double Circle::cal_zc()
{
	return 2*PI*R;
}
	
double Circle::cal_mj()
{
	return PI*R*R;
}

(4)class与struct的区别:

        class默认权限为私有private

        struct默认权限为公共public

struct A
{
    int iNum;
}

class B
{
    int iNum;
}

A a;
a.iNum=2;//没有问题,struct默认权限为public

B b;
b.iNum=2;//编译出错,class默认权限为private

2.创建对象:

(1)对象的初始化和清理:

        对象的初始化和清理是两个非常重要的安全问题。一个对象或者变量没有初始化状态,对其使用后果是未知的。使用完一个对象或变量,没有及时清理也会造成一定的安全问题。

        C++利用构造函数和析构函数解决上述问题,这两个函数会被编译器自动调用。

(2)构造函数:

        构造函数主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动调用。

1)构造函数的结构:

class Person
{
public:

    //有参构造函数
    Person(string name, int age)
    {
        this->name=name;
        this->age=age;
    }
    //this是一个指向当前类的指针

    //拷贝构造函数
    Person(const Person& p)
    {
        this->name=p.name;
        this->age=p.age;
    }
    //拷贝构造中传入的参数是以引用的方式传入,可节省空间
    //const是为了确保不改变传入的参数p

public:
    string name;
    int age;
};

        该Person类中有两个属性name和age,利用函数重载机制编写了有参构造和拷贝构造两种构造函数,编译器会根据调用时参数的不同,自动选择正确的构造函数。在不提供构造函数时,编译器会自动提供一个默认的无参构造函数。

2)构造函数的调用方法:

#include 
#include
using namespace std;

class Person
{
public:
	//有参构造函数
	Person(string name, int age)
	{
		this->name = name;
		this->age = age; 
	}
	
	//拷贝构造函数
	Person(const Person& p)
	{
		this->name = p.name;
		this->age = p.age; 
	} 
	
public:
	string name;
	int age;
};

void test01()
{
	Person p1("Tom",10);//括号法
	
	Person p2 = Person("John",20);//显式构造法
	
	Person p3 = { "Harry",30 };//隐式构造法
	
	Person p4(p2);//拷贝构造
	
	cout << p1.name << " " << p1.age << endl;
	cout << p2.name << " " << p2.age << endl;
	cout << p3.name << " " << p3.age << endl;
	cout << p4.name << " " << p4.age << endl;
}
 int main()
{
    test01();
    
    return 0;
}

        有参构造函数有三个调用方法:括号法,显式法,隐式法。

        拷贝构造则是在创建对象p4的时候直接传入一个已有的Person对象p2,利用p2的属性初始化p4。

ROS学习笔记5:C++基础知识_第2张图片

(3)析构函数:

        析构函数主要作用在于对象销毁前系统自动调用,执行一些清理工作。析构函数在对象消亡时自动调用。析构函数名与类名相同,前面加~,没有参数和返回值。

#include
using namespace std;

class Person
{
public:
	
	//有参构造函数
    Person(string name, int age)
    {
        this->name=name;
        this->age=age;
        cout<<"构造函数调用"<

ROS学习笔记5:C++基础知识_第3张图片

         运行结果显示了一个对象从创建到消亡的过程。在“析构函数调用”后打印输出“1111”,说明在执行完函数test02()时析构函数立即被调用,代表在函数中创建的对象被销毁。

3.静态成员:

(1)定义:

        在成员变量和成员函数前加上关键字static称为静态成员。静态成员分为静态成员变量静态成员函数

1)静态成员变量:

        所有对象共享同一份数据;在编译阶段分配内存;类内声明,类外初始化。

2)静态成员函数:

        所有对象共享同一个函数;静态成员函数只能访问静态成员变量。

class Runoob
{
public:
    static int runoob_age;//静态变量
    int runoob_users;//实例变量

public:
    func
    {
        int runoob_local;//局部变量
    };
};

(2)静态成员访问:

        访问方式有两种:对象.或者类名::

#include
using namespace std;

class Person
{
public:

    static int count;//静态成员变量
    string name;

};

int Person::count=10;//类外初始化

void test01()
{
    Person p1;
    p1.name="Tom";
    cout<<"p1的名字:"<

        count是Person类中的一个静态成员变量,可以用p1.count和Person::count两种方式来访问。而name是Person类中的一个普通成员变量,只能用p1.name的方式访问。

运行结果如下:

ROS学习笔记5:C++基础知识_第4张图片

(3)示例:创建了两个对象,都对count属性进行了改变

#include
using namespace std;

class Person
{
public:

    static int count;//静态成员变量
    string name;

};

int Person::count=10;//类外初始化

void test01()
{
    Person p1;
    p1.count=0;
	cout<<"count:"<

运行结果如下:

ROS学习笔记5:C++基础知识_第5张图片

        运行结果说明Person类的所有对象共享同一个变量count。

4.访问权限:

(1)数据封装:

        数据封装是面向对象编程的一个重要特点,它防止函数直接访问类的内部成员。类成员的访问限制是通过在类主体内部对各个区域标记public、private、protected来指定的。public、private、protected称为访问修饰符。

        一个类可以有多个访问修饰符标记区域,类默认的访问修饰符是ptivate。

(2)访问修饰符:

1)public:公有成员,可以在任何地方访问。

2)private:私有成员,只能在类中或者友元函数中访问。

3)protected:保护成员,可以在类中的函数、子类函数及友元函数中访问。

分析示例:

#include
using namespace std;

class Person
{
	//姓名,公共权限
public:
    string m_Name;
	
	//汽车,保护权限
protected:
    string m_Car;
	
	//银行卡密码,保护权限
private:
    int m_Password;
	
public:
    void func()
	{
	    m_Name="张三";
		m_Car="拖拉机";
		m_Password=123456; 
		
		cout<

输出结果如下:

   ROS学习笔记5:C++基础知识_第6张图片      

        在这个例子中可以看出,func()作为成员函数可以访问私有成员变量和保护成员变量,然而在类外函数test01()中就不能访问m_Car和m_Password。

(3)友元:

        类的友元函数是定义在类外部,但有权访问类的所有私有成员和保护成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。

        友元可以是一个函数(友元函数),也可以是一个类(友元类),在这种情况下,整个类及其所有成员都是友元。

示例:

#include
using namespace std;

class Box
{
	double width;
public:
	friend void printWidth(Box box);
	void setWidth(double wid);
};

//成员函数定义
void Box::setWidth(double wid)
{
	width=wid;
}

//请注意:printWidth()不是任何类的成员函数
void printWidth(Box box)
{
	/*因为printWidth()是Box的友元,它可以直接访问该类的任何成员*/
	cout<<"Width of box:"<

输出结果:

ROS学习笔记5:C++基础知识_第7张图片

你可能感兴趣的:(ROS编程技术,学习)