C++谷歌开源项目风格参考指南:
zh-google-styleguide.readthedocs.io
C++参考手册:
C++ & QT国内学习网站:
C++错误语法调试:
Q: istream类去执行以下赋值构造函数时, 会出现以下报错
error: use of deletec function ‘std::basic_istream<char>::basic_istream(const std::basic_istream<char&>)’
A: 在c++11的标准中,为函数增添一个新的属性,delete, 因此,当我们使用到stream的赋值构造函数时候, 就会显示该函数已被删除, 无法执行。
如下代码:
basic_istream( const basic_istream& rhs ) = delete;
Q: 关于引用的一些注意补充。
注意:1. 当对象传递给引用的时候,只是一个指针传递,不会涉及到构造函数的运行,也不会有新的对象被创建。 2. 函数的局部对象变量,不能被当作引用传递出来, 因为局部对象变量会被自动销毁, 那么引用的对象是违法地址。
类似警告如下:
warning: reference to local variable ''is" returned.
Q:error: invalid use of non-static member function ‘bool MyClass::cmp(int, int)’
A: 初学者经常犯的错误, 由于类内部的定义,只有在变量为static成员时, 才能通过域操作符::直接调用该变量,除了static成员, 枚举变量也可以,因为枚举变量存储在常量型存储区域。 如果非static成员的话, 不能直接当作左值直接使用, 而是要通过对象去调用。在ros中, 如果传递回调函数的话, 同时也要传递相应的对象, 这样, 回调函数需要this指针才能调用。
Q: 假设fun是函数名,那么在c++中, 关于函数地址如何理解
对于 fun 和 &fun 应该这样理解:fun 是函数的首地址,它的类型是 void ()
&fun 表示一个指向函数 fun 这个对象的地址, 它的类型是 void (*)()
因此 fun 和 &fun 所代表的地址值是一样的,但类型不一样, 和数组名类似的语法。
Q: C++函数的返回值为右值, 这些值存储在寄存器中, 而不是在内存之中。
Q:在使用image_transport进行视频压缩传输的时候, 会出现以下报错, 究其原因其实很简单, 就是image_transport库中没有无参数的默认构造函数, 笔者在头文件声明中调用了 "image_transport::image_transport a"去声明变量,要注意的是, 编译器会按照变量声明的形式去执行构造函数,因此在初始化新的对象的时候,就会调用无参数的构造函数, 为了避免在声明中执行构造函数, 可以创建该对象的指针, 然后在构造函数new一个对象出来。
在类中,会优先执行初始化列表,初始化列表没有先后顺序之分( 如果成员对象已经在初始化列表执行了, 则在后续声明中,不会再进行成员对象的构造函数了, 甚至早于类构造函数的执行),执行完之后,会再执行类的构造函数, 而类中先声明的对象先调用构造函数。
error: no matching function for call to ‘image_transport::ImageTransport::ImageTransport()’
,video_framerate(0)
/opt/ros/melodic/include/image_transport/image_transport.h:54:12: note: candidate: image_transport::ImageTransport::ImageTransport(const ros::NodeHandle&)
explicit ImageTransport(const ros::NodeHandle& nh);
^~~~~~~~~~~~~~
/opt/ros/melodic/include/image_transport/image_transport.h:54:12: note: candidate expects 1 argument, 0 provided
/opt/ros/melodic/include/image_transport/image_transport.h:51:7: note: candidate: image_transport::ImageTransport::ImageTransport(const image_transport::ImageTransport&)
class ImageTransport
Q:类中常常会有对象成员,我们常常需要对类中的对象成员进行初始化构造, 但是, 有时候, 该对象成员有时需要传递多个形参进行构造, 此时, 我们该如何声明, 该如何构造? 如下class_b b对象需要多个形参进行构造初始化, 那么在声明的时候, 仍然按照默认构造函数声明, 然后,在初始化列表中, 传递参数给b对象, 那么此时就是显式调用多形参的构造函数, 初始化列表的构造优先级大于类内部的构造函数,不止可以初始化变量, 也可以初始化对象。
class a{
public:
a();
a(int a);
class_b b;
}
/* 通过初始化列表,传递参数给对象b, 对对象b进行构造 */
a::a(int a):b(a,a)
{
}
此外, 还有另外一个办法, 就是声明的时候, 先暂时创建一个对象成员的指针, 而后在类中的构造函数new一个对象传递给该指针。
Q:上个问题的扩展延伸, 初始化列表里面变量的编写程序无法决定成员变量的初始化顺序, 初始化列表只能说, 先进行初始化, 但是每一个变量的初始化顺序, 仍然是由声明的时候的定义顺序决定, 这个地方要特别注意。当我们在初始化列表中, 初始化一个变量时, 而这个变量又调用了其他成员变量, 那么在声明的时候, 被调用的成员变量要写在前面,以保证被调用成员变量先进行初始化。如下代码示例:nh_变量在声明时要写在as_变量的前面。
#include <ros/ros.h>
#include <std_msgs/Float32.h>
#include <actionlib/server/simple_action_server.h>
#include <actionlib_tutorials/AveragingAction.h>
class AveragingAction
{
public:
AveragingAction(std::string name) :
as_(nh_, name, false),
action_name_(name)
{
//register the goal and feeback callbacks
as_.registerGoalCallback(boost::bind(&AveragingAction::goalCB, this));
as_.registerPreemptCallback(boost::bind(&AveragingAction::preemptCB, this));
}
protected:
ros::NodeHandle nh_;
actionlib::SimpleActionServer<actionlib_tutorials::AveragingAction> as_;
};