C++重载<<运算符错误

4

我希望能够得到一些关于我遇到的错误的帮助-我已经搜索了类似的问题,但并没有给我想要的答案。以下是代码片段:

class NewSelectionDlg : public CDialog
{
// Construction
public:

  class CProductListBox
  {
    public:
    friend ostream& operator <<(ostream& o, const CProductListBox& b);
  };
   ostream& operator<<(ostream& o,  const CProductListBox& b)
  {
        std::cout << o.m_lstEclispeProducts;
        return o;
  }

我有一个列表框,其中包含许多字符串 - 这些字符串可能会因选择其他下拉框而异。我想将此框中的内容以及用户从弹出菜单中选择的内容写入文件。然而,我遇到了以下错误(我正在使用VS 2008进行开发)。

error C2804: 二进制 'operator <<' 的参数太多
error C2333: 'NewSelectionDlg::operator <<' : 函数声明中有错误;跳过函数体

我不确定为什么会出现这种情况,因为我认为重载运算符的语法是正确的 - 有人能看出我做错了什么或者可能忽略了什么吗?非常感谢任何帮助。
6个回答

5
只需在类定义之外定义它,或在声明友元时在子类中定义它即可:

class NewSelectionDlg : public CDialog
{
// Construction
public:

  class CProductListBox
  {
    public:
    friend ostream& operator <<(ostream& o, const CProductListBox& b);
  };

// (...) Rest of NewSelectionDlg
}; 

ostream& operator <<(ostream& o, const NewSelectionDlg::CProductListBox& b)
{
    // Did you meant:
    return o << b.m_lstEclispeProducts;
} 

或者

class NewSelectionDlg : public CDialog
{
// Construction
public:

  class CProductListBox
  {
    public:
    friend ostream& operator <<(ostream& o, const CProductListBox& b)
    {
        // Did you meant:
        return o << b.m_lstEclispeProducts;
    }
  };

// (...) Rest of NewSelectionDlg
}; 

嗨,Pawel - 感谢你的帮助 - 如果你能帮忙,我发布了另一个问题 - 谢谢。 - user617702

3

operator <<不应该是成员函数。第一个参数必须是std::ostream;在你的代码中,第一个(隐式)参数是this指针,即NewSelectionDlg*类型的对象。

你需要将operator <<实现为自由函数。


1

你应该在 NewSelectionDlg 的定义之外定义重载的 operator<<,并相应地限定作用域为 CProductListBox

ostream& operator<<(ostream& o, const NewSelectionDlg::CProductListBox& b)
{
    ...
}

非常感谢大家提供的所有建议 - 我会逐一处理并告诉你们结果。 - user617702

0
另外,应该是在“<<:”中使用b而不是o吗?
    std::cout << o.m_lstEclispeProducts;

0

我选择了你的第二个方案。

class NewSelectionDlg : public CDialog
{
// Construction
public:

  class CProductListBox
  {
    public:
    friend ostream& operator <<(ostream& o, const CProductListBox& b)
    {

       return o << b.m_lstEclispeProducts;
    }
  };

我仍然遇到一个错误 - 错误C2039:'m_lstEclispeProducts':不是'NewSelectionDlg :: CProductListBox'的成员

我不确定为什么会出现这种情况,因为NewSelectionDlg类的一部分包含此代码(相关行用粗体标出)- 如果您有任何进一步的帮助/建议,那将是非常有帮助的。谢谢

// Dialog Data

//{{AFX_DATA(NewSelectionDlg)

  enum { IDD = IDD_NEW_SELECTION };

  CButton   m_btnMessageBoard;

  CButton m_btnMoreInfo;

  CComboBox m_cmbOpenDocuments;

  CButton m_btnOk;

  CButton m_btnStateApprovals;

  CComboBox m_cmbProductType;

///  CListBox  m_lstSalesConcepts;

  CButton   m_chkObjectiveWizard;

  **CProductListBox  m_lstEclipseProducts;**

这是因为m_lstEclispeProductsNewSelectionDlg的成员,而不是NewSelectionDlg::CProductListBox的成员。您如何使用此代码?考虑向NewSelectionDlg::CProductListBox添加一个变量,存储要打印对象的m_lstEclispeProducts - Pawel Zubrycki
1
Stack Overflow不是一个论坛,而是一个略有不同的工具。试图基于答案建立讨论并不是一个好主意,因为答案在每次页面重新加载时都会被重新排序。如果您想对某个答案发表评论,只需使用评论框即可。在这种特殊情况下,您应该创建一个不同的问题,因为现在的问题与原始问题无关。我理解对于初学者来说这可能不是很明显 :) - David Rodríguez - dribeas
现在,针对您的特定问题,在C++中,内部类无法访问外部类,因此如果您想要访问外部类成员,您应该在外部类级别提供该功能。 - David Rodríguez - dribeas
谢谢David - 我是论坛的新手 - 以后会注意的。Pawel - 我认为我可能需要稍微不同的方法来做这件事 - CProductListBox有一个单独的头文件 - //CProductListBox class CProductListBox : public CListBox {DECLARE_DYNAMIC(CProductListBox) public: CProductListBox(); virtual ~CProductListBox();protected: DECLARE_MESSAGE_MAP() public: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct); }; 是否最好将重载<<代码添加到此处以使其正常工作。谢谢 - user617702

0

当你使用以下声明:

friend void foo();

你所做的是在封闭的命名空间范围内声明一个函数。

namespace name {
   struct outer {
      struct inner {
         friend void foo(); // declares name::foo
      };
   };
   void foo() {} // defines it
}

同样适用于运算符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接