英文:
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
类内外声明TObjectList
和Chord
。每种方式都会生成不同的错误消息。我应该使用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<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
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 <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
Here is the cpp file:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
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 <System.Generics.Collections.hpp>
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<TObjectList>
to not have to manually delete
it later.
Note: However, Chord
is not derived from System::TObject
so using TObjectList
for storing Chord
s is not going to work (unless you make Chord
inherit from TObject
). That is because TObjectList
stores TObject*
. I suggest using a std::vector<Chord>
instead.
Regarding:
[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
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论