【问题标题】:What does it mean to use the * operator before a reference to a class in this example在此示例中,在对类的引用之前使用 * 运算符是什么意思
【发布时间】:2015-11-03 01:16:20
【问题描述】:

Eclipse IDE 在下一行向我抛出一个错误,即“方法'get' 无法解析”。确切的错误信息是

Method 'get' could not be resolved, Location: line xxx, Type: Semantic Error

错误行:

const TagValue* tagValue = ((*mktDataOptions)[i]).get();

这里出了什么问题?这段代码是作为 API 提供给我的,所以想必其他人之前已经使用过它。类似的错误在给我的代码中出现了大约 8 次,我很难相信它在 8 次不同的时间中以相同的方式编码错误。

问题

有人可以为我解析这条线并准确解释它想要做什么吗?
为什么我的 Eclipse 对所有这些实例都抛出错误,如何解决?

相关代码

函数中存在这一行:

void EClient::reqMktData(TickerId tickerId, const Contract& contract, 
const std::string& genericTicks, bool snapshot, const TagValueListSPtr& mktDataOptions)
...
    if( m_serverVersion >= MIN_SERVER_VER_LINKING) {
        std::string mktDataOptionsStr("");
        const int mktDataOptionsCount = mktDataOptions.get() ? mktDataOptions->size() : 0;
...
                const TagValue* tagValue = ((*mktDataOptions)[i]).get();

其中“TagValueListSPtr”在标头中定义为

struct TagValue
{
    TagValue() {}
    TagValue(const std::string& p_tag, const std::string& p_value)
        : tag(p_tag), value(p_value)
    {}

    std::string tag;
    std::string value;
};

typedef shared_ptr<TagValue> TagValueSPtr;
typedef std::vector<TagValueSPtr> TagValueList;
typedef shared_ptr<TagValueList> TagValueListSPtr;

而“shared_ptr”被定义为

template<typename X> class shared_ptr {
public:

   typedef shared_ptr_defs::Use Use;

   template<typename Y> friend class shared_ptr;

   explicit shared_ptr(X* ptr = 0) : ptr_(ptr) {}

   ~shared_ptr() { if (use_.only()) delete ptr_; }

   template<typename Y>
   shared_ptr(const shared_ptr<Y>& other)
      : ptr_(other.ptr_),
        use_(other.use_)
      {}

   shared_ptr& operator=(const shared_ptr& other) {
      if ( &use_ == &other.use_ ) { return *this; }
      if ( use_.only() ) { delete ptr_; }
      use_ = other.use_;
      ptr_ = other.ptr_;
      return *this;
   }

   X& operator*()  const { return *ptr_; }
   X* operator->() const { return ptr_; }
   X* get()        const { return ptr_; }
   bool only() const { return use_.only(); }

   void reset(X* ptr = 0) {
      if ( use_.only() ) { delete ptr_; }
      ptr_ = ptr;
      use_ = Use();
   }

private:

   X *ptr_;
   Use use_;
};

【问题讨论】:

  • 你能添加确切的错误信息吗?这听起来像是一个链接器错误。
  • ....虽然get 是内联的,所以这可能不是问题。
  • * 表示取消引用指针。 *mktDataOptions 是指向的对象(它是一个向量)。 mktDataOptions 是指针。 (*mktDataOptions)[i] 访问向量的ith 成员。
  • 我在代码块的顶部添加了来自 Eclipse 的确切消息(请忽略着色)。不确定它有多大帮助。
  • 很多...这是来自 Eclipse 的错误消息,而不是编译器。话虽如此,它编译了吗? (然后跑?)

标签: c++ eclipse


【解决方案1】:

谁能帮我解析一下这行代码并准确解释它想要做什么?

/* A pointer (to a const qualified TagValue) */
const TagValue*
/* named */ tagValue
/* is initialised to the result of */ = ((
/* dereferencing */ *
/* the shared pointer */ mktDataOptions)
/* which points to a vector */
/* and calling operator[] on it */ [i])
/* which returns the reference to */
/* a shared pointer to a TagValue */
/* whose */ .get();
/* member function is called, returning /*
/* as final result a pointer to a TagValue */

这实际上是一个非常复杂的设计,涉及所有权(涉及很多共享指针),这就是为什么我怀疑这是否真的需要,但是很好。

mktDataOptions 是一个指向包含指向TagValues 的共享指针的向量的共享指针。因此,要获得指向TagValue 的指针,您需要使用shared_ptr::operator*() 取消引用指向向量的指针,使用其std::vector::operator[]() 选择该向量的元素(ith)。这是一个指向TagValue 的共享指针,因此要获取底层指针,需要应用成员函数shared_ptr::get()

您可以将其重写为...

// using references, otherwise you make copies,
// which changes the meaning of the code.

// Get the vector from the shared pointer
std::vector<shared_ptr<TagValue>> & the_vector = *mktDataOptions;

// get a single element from it
shared_ptr<TagValue> const & the_element = the_vector[i];

// get it's underlying pointer
TagValue * the_pointer = the_element.get();

// it's a pointer to a non const TagValue, which can be
// converted to a pointer to a const TagValue (the type of the variable
// which gets initialised)
TagValue const * tagValue = the_pointer;

为什么我的 Eclipse 对所有这些实例都抛出错误,如何解决?

[...] 这是一个我应该随意忽略的 Eclipse 错误吗?我还是想摆脱它。

根据一些研究,这似乎是一个 eclipse 错误,可以通过删除 workspace/.metadata 来解决,但我需要注意我不是 eclipse 用户,所以我无法验证或推荐一些可能的解决方案。

在您的情况下,我会复制工作区和项目目录,然后开始尝试以下建议:

但从这些问题来看,这似乎是一个比较奇怪的错误,所以要准备一些挫折。

【讨论】:

  • 请重新格式化您的答案,使其清晰易读。将其嵌入到 cmets 中不符合条件。
  • @EJP 请阅读整个答案:我将 cmets 嵌入到有问题的实际源代码行中,但还提供了文本描述以及等效的、更易于理解的代码。
  • @Daniel Jour。这非常有帮助——谢谢。我应该注意我并没有绑定到 Eclipse。除了 Eclipse IDE 之外,还有更好的选择来处理大型项目 API 吗?人们实际上是否曾经在 vim 中执行此操作并使用 g++ 进行编译?为这些问题道歉——这是我的第一个更大的项目之一。
  • 很高兴它可以帮助你:) 我正在使用 vim 和 Emacs 做我的工作,使用 makefile 来处理构建等。我个人不喜欢 eclipse,但它似乎是一个经常使用的 IDE。我猜对于 C++ 项目,makefile 或 cmake 是构建软件的良好、可移植的方式,允许您使用任何最适合的编辑器/IDE(包括 eclipse)。 (当然,使用一些版本控制软件,比如 git)
猜你喜欢
  • 2015-01-25
  • 2016-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 2011-01-01
  • 2017-01-15
  • 2016-04-15
  • 2023-03-21
相关资源
最近更新 更多