不理解关于类声明和使用与List对象相关的错误消息。

huangapple go评论67阅读模式
英文:

Not understanding error messages about a class declaration and usage with List objects

问题

我正在为Windows编写一个VCL应用程序。在学习更多关于C++和使用更现代技术的过程中,我将以下结构转换为可用的类(我认为)并使用`TObjectList`创建了一个有序列表。

这些是我转换的旧结构声明:

```c++
typedef struct chord {
	char cKey[6];
	char cRank[30];
	int  cFret;
	char cPos[40];
	char cPlay[6];
} CHORD;

typedef struct double_list {
  char   *key;
  int    element_marked;
  CHORD  *data;
  struct double_list *next;
  struct double_list *prior;
} DLIST;

当我按照下面所示编译代码时,对于全局变量声明,我收到了以下错误消息,我也不明白。

TObjectList<Chord> chordList;
Chord chordObj;

[bcc32c Error] Unit1.h(38): expected unqualified-id
[bcc32c Error] Unit1.h(39): must use 'class' tag to refer to type 'Chord' in this scope
  wingdi.h(3740): class 'Chord' is hidden by a non-type declaration of 'Chord' here

我尝试过在TForm1类内外声明TObjectListChord。每种方式都会生成不同的错误消息。我应该使用TList还是TObjectList,或者在列表对象的某个版本中使用其他版本,考虑到列表中将会有数百个Chord对象?

我完全困惑了。对于正在发生的事情的任何澄清,以及要使用的最佳实践和方法,我将不胜感激。

以下是头文件:

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <System.Contnrs.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <string>

//---------------------------------------------------------------------------

typedef std::string string;

class Chord {
private:
protected:
public:
	string searchKey;
	string cKey;
	string cRank;
	int    cFret;
	string cPos;
	string cPlay;

	Chord() {}
	Chord(string ck,string cr,int cf,string cp,string csp) {
		cKey=ck;
		cRank=cr;
		cFret=cf;
		cPos=cp;
		cPlay=csp;
	}
};

TObjectList<Chord> chordList;
Chord chordObj;

//---------------------------------------------------------------------------

class TForm1 : public TForm
{
__published:	// IDE-managed Components
private:	// User declarations
public:		// User declarations

	__fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

以下是cpp文件:

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
英文:

I am writing a VCL application for Windows. In the process of learning more about C++ and using more modern techniques, I have converted the following structures into a usable class (I think) and an ordered list by using TObjectList.

These are the old structure declaration I converted:

typedef struct chord {
	char cKey[6];
	char cRank[30];
	int  cFret;
	char cPos[40];
	char cPlay[6];
} CHORD;

typedef struct double_list {
  char   *key;
  int    element_marked;
  CHORD  *data;
  struct double_list *next;
  struct double_list *prior;
} DLIST;

When I compile the code as shown below, I received the following error messages for the global variable declarations, and I don't understand either.

TObjectList&lt;Chord&gt; chordList;
Chord chordObj;

[bcc32c Error] Unit1.h(38): expected unqualified-id
[bcc32c Error] Unit1.h(39): must use &#39;class&#39; tag to refer to type &#39;Chord&#39; in this scope
  wingdi.h(3740): class &#39;Chord&#39; is hidden by a non-type declaration of &#39;Chord&#39; here

I have tried to declare the TObjectList and Chord both inside and outside of the TForm1 class. Each way it generates different error messages. Should I be using TList versus TObjectList, or some other version of a List object, given there will be hundreds of Chord objects in the list?

I'm completely stumped. Any clarification of what is going on, and best practices and methods to use, would be greatly appreciated.

Here is the header file:

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include &lt;System.Classes.hpp&gt;
#include &lt;System.Contnrs.hpp&gt;
#include &lt;Vcl.Controls.hpp&gt;
#include &lt;Vcl.StdCtrls.hpp&gt;
#include &lt;Vcl.Forms.hpp&gt;
#include &lt;string&gt;

//---------------------------------------------------------------------------

typedef std::string string;

class Chord {
private:
protected:
public:
	string searchKey;
	string cKey;
	string cRank;
	int    cFret;
	string cPos;
	string cPlay;

	Chord() {}
	Chord(string ck,string cr,int cf,string cp,string csp) {
		cKey=ck;
		cRank=cr;
		cFret=cf;
		cPos=cp;
		cPlay=csp;
	}
};

TObjectList&lt;Chord&gt; chordList;
Chord chordObj;

//---------------------------------------------------------------------------

class TForm1 : public TForm
{
__published:	// IDE-managed Components
private:	// User declarations
public:		// User declarations

	__fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Here is the cpp file:

//---------------------------------------------------------------------------

#include &lt;vcl.h&gt;
#pragma hdrstop

#include &quot;Unit1.h&quot;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource &quot;*.dfm&quot;
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------

答案1

得分: 2

关于
```[bcc32c错误] Unit1.h(38): 期望未限定标识符```

然后根据文档包含定义TObjectList的文件:

#include <System.Generics.Collections.hpp>

并且不要给它一个模板参数,并且像大多数VCL类一样使用new进行分配:

auto chordList = new TObjectList;

您可以将原始拥有指针存储在std::unique_ptr<TObjectList>中,以免以后手动删除它。

注意: 但是,Chord未派生自System::TObject,因此使用TObjectList来存储Chord将不起作用(除非您让Chord继承自TObject)。这是因为TObjectList存储TObject*。我建议改用std::vector<Chord>


关于:
[bcc32c错误] Unit1.h(39): 必须在此范围中使用'类'标记来引用类型'Chord'
wingdi.h(3740): 类'Chord'被此处的非类型声明'Chord'隐藏

在`wingdi.h`,第3740行,您会在全局命名空间中找到此声明:
```c++
WINGDIAPI BOOL WINAPI Chord( _In_ HDC hdc, _In_ int x1, _In_ int y1, _In_ int x2, _In_ int y2, _In_ int x3, _In_ int y3, _In_ int x4, _In_ int y4);

您的类Chord与此Chord函数发生冲突,因此您需要重命名该类或将其放在一个命名空间中。

另一个选项可能是通过首先添加class来引用该类:

class Chord chordObj;

但这将是一个相当不符合惯例的解决方案。


<details>
<summary>英文:</summary>

Regarding

[bcc32c Error] Unit1.h(38): expected unqualified-id

Then include the file that is defining `TObjectList` according to [the documentation](https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.Generics.Collections.TObjectList):
```c++
#include &lt;System.Generics.Collections.hpp&gt;

and don't give it a template parameter and allocate it with new as is common for most VCL classes:

auto chordList = new TObjectList;

You could store the raw owning pointer in a std::unique_ptr&lt;TObjectList&gt; to not have to manually delete it later.

Note: However, Chord is not derived from System::TObject so using TObjectList for storing Chords is not going to work (unless you make Chord inherit from TObject). That is because TObjectList stores TObject*. I suggest using a std::vector&lt;Chord&gt; instead.


Regarding:

[bcc32c Error] Unit1.h(39): must use &#39;class&#39; tag to refer to type &#39;Chord&#39; in this scope
  wingdi.h(3740): class &#39;Chord&#39; is hidden by a non-type declaration of &#39;Chord&#39; here

In wingdi.h, line 3740, you'll find this declaration in the global namespace:

WINGDIAPI BOOL WINAPI Chord( _In_ HDC hdc, _In_ int x1, _In_ int y1, _In_ int x2, _In_ int y2, _In_ int x3, _In_ int y3, _In_ int x4, _In_ int y4);

Your class Chord collides with this Chord function, so you need to rename the class or put it in a namespace.

Another option could be to refer to the class by adding class first:

class Chord chordObj;

but, that would be a rather non-idiomatic solution.

huangapple
  • 本文由 发表于 2023年6月26日 02:43:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76551931.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定