构造函数的返回类型定义 - 如何修复此标头

Posted

技术标签:

【中文标题】构造函数的返回类型定义 - 如何修复此标头【英文标题】:Return type definition for a constructor - howto fix this header 【发布时间】:2012-01-05 13:09:04 【问题描述】:

我有一个头文件,用于 GNU 无线电信号处理块,并用于定义 C++ API。正如我在 cmets 中所写,它使用“朋友”定义以安全的方式处理 Boost Shared Pointers,这样就不会发生意外的原始指针(访问私有构造函数)。

我真的不能说为什么这会失败。它似乎与构造函数中使用的标识符有关。顺便说一句,类定义。以“;”结尾;)

我的构建错误消息是(我用 [point n] 标记了有问题的行。

cogra_binary_slicer.h:64:66: 错误:返回类型规范 构造函数无效 [第 1 点] cogra_binary_slicer.cc:在函数中 'cogra_binary_slicer_sptr cogra_binary_slicer()': cogra_binary_slicer.cc:42:41: error: expected type-specifier [POINT 2] before 'cogra_binary_slicer' cogra_binary_slicer.cc:42:41:错误:预期 ')' 在'cogra_binary_slicer' cogra_binary_slicer.cc:42:63 之前:错误: 无法使用 T = int 转换“gnuradio::get_initial_sptr(T*)” 从‘boost::shared_ptr’到‘cogra_binary_slicer_sptr aka boost::shared_ptr'

然而,这将其缩小到三个文件。

头文件 cogra_binary_slicer.h:

#ifndef INCLUDED_COGRA_BINARY_SLICER
#define INCLUDED_COGRA_BINARY_SLICER

#include <cogra_api.h>
#include <gr_block.h>

class cogra_binary_slicer;

typedef boost::shared_ptr<cogra_binary_slicer> cogra_binary_slicer_sptr;

/*!
 * \brief Return a shared_ptr to a new instance of cogra_binary_slicer.
 *
 * To avoid accidental use of raw pointers, cogra_binary_slicer's
 * constructor is private.  cogra_binary_slicer is the public
 * interface for creating new instances.
 */
COGRA_API cogra_binary_slicer_sptr cogra_binary_slicer ();


class COGRA_API cogra_binary_slicer : public gr_block

private:
  // The friend declaration allows cogra_binary_slicer to
  // access the private constructor.


  // [POINT 1]
  friend COGRA_API cogra_binary_slicer_sptr cogra_binary_slicer ();

  cogra_binary_slicer ();   // private constructor

 public:
  ~cogra_binary_slicer ();  // public destructor

  // Where all the action really happens

  int general_work (int noutput_items,
            gr_vector_int &ninput_items,
            gr_vector_const_void_star &input_items,
            gr_vector_void_star &output_items);
; // yes

#endif /* INCLUDED_COGRA_BINARY_SLICER */

cogra_binary_slicer.cc,创建实例的位置(失败)。标有 [POINT 2] 的故障点:

#include <cogra_binary_slicer.h>
#include <gr_io_signature.h>

/*
 * Create a new instance of cogra_binary_slicer and return
 * a boost shared_ptr.  This is effectively the public constructor.
 */
cogra_binary_slicer_sptr 
cogra_binary_slicer ()

  return gnuradio::get_initial_sptr(new cogra_binary_slicer ()); **[POINT 2]**

还有 API 标头 cogra_api.h:

#ifndef INCLUDED_COGRA_API_H
#define INCLUDED_COGRA_API_H

#include <gruel/attributes.h>

#ifdef gnuradio_cogra_EXPORTS
#  define COGRA_API __GR_ATTR_EXPORT
#else
#  define COGRA_API __GR_ATTR_IMPORT
#endif

#endif /* INCLUDED_COGRA_API_H */

我附上了这么多来源,因为我无法缩小编译在特定位置失败的原因。

为什么我的返回类型无效的一些指示可能会有所帮助。

【问题讨论】:

您的 friend 语法看起来不正确。这不应该是friend class cogra_binary_slicer_sptr;吗? 也许你不能有一个同名的类和函数? @visitor 是对的。如果你想要一个工厂函数,它必须被命名为别的东西。 【参考方案1】:

将您的创建函数重命名为除类名之外的其他名称:

friend COGRA_API cogra_binary_slicer_sptr cogra_binary_slicer ();

否则,编译器可能会将其视为具有 areturn 类型的构造函数。

【讨论】:

【参考方案2】:

你应该重命名你的类或cogra_binary_slicer函数。

考虑这个编译良好的例子:

class A;
A* B();


class A
    friend A* B();
    A();
public:
    A(int i)
;

A* B() return new A();  

而这个失败并出现错误“错误 C2380: type(s) before 'A' (constructor with return type, or invalid redefinition of current class-name?)”

class A;
A* A();


class A
    friend A* A();
    A();
public:
    A(int i)
;

A* A() return new A();  

另外,你应该考虑在你的类中使用公共静态成员函数:

class A
    A();
public:
    A(int i)
    static A* getInstance() return new A(); 
;

【讨论】:

【参考方案3】:

在函数定义中,cogra_binary_slicer 指的是函数,而不是类。

您需要将new cogra_binary_slicer 更改为new class cogra_binary_slicer

但是,在类定义中,cogra_binary_slicer 将始终引用类,所以我认为没有任何方法可以使函数成为朋友。所以我认为你唯一的选择是给类和函数起不同的名字。这也有助于减少混淆。

【讨论】:

以上是关于构造函数的返回类型定义 - 如何修复此标头的主要内容,如果未能解决你的问题,请参考以下文章

拷贝构造函数

如何修复此错误:未捕获(承诺)类型错误:无法读取未定义的属性(读取“长度”)

第 13 章

在与标头分开的 cpp 中定义私有类函数时出错

拷贝构造函数

构造函数