"Error: expression must have class type" on reference to member of ref struct C++/CLI

"Error: expression must have class type" on reference to member of ref struct C++/CLI

我在这个网站上搜索了 post,虽然还有其他几个人有相同的错误消息,但它们似乎不适用于我遇到的问题。

我在 visual studio 2013 社区版中将 C++/CLI 与 .NET 框架结合使用。我在 header 文件中定义了一个 ref structPoint.h,然后我在 header 文件中创建了一个 windows 的实例] 形式,MainForm.h。 (在MainForm.h里面没有Point.h的语句Point.h,因为它包含在FractalScript.h里面,而在MainForm.h

里面

每当我尝试访问 struct 实例的任何成员变量时,我都会收到标题中提到的错误。我不会 post 我的整个源代码,因为其中一些完全独立于此问题并且与此问题无关。但是,如果您想查看我的全部源代码,我可以 post 它。

Main.cpp

 #include "MainForm.h"

 int main()
 {
     FractalGenerator::MainForm m;
     m.ShowDialog();

     return 0;
 }

Point.h

 namespace point
 {
     ref struct Config
     {
         //float width is the width in pixels of the shape
         float width;

         //float height is the height in pixels of the shape
         float height;

         //float x is the x coordinate in pixels of the top-left corner of  the shape
         float x;

         //float y is the y coordinate in pixels of the top-left corner of the shape
         float y;

         //int argb_a is the alpha channel of the colour of the shape (value between 0 and 255)
         int argb_a;

         //int argb_r is the red channel of the colour of the shape (value between 0 and 255)
         int argb_r;

         //int argb_g is the green channel of the colour of the shape (value between 0 and 255)
    int argb_g;

         //int argb_b is the blue channel of the colour of the shape (value between 0 and 255)
         int argb_b;
     };
 }

MainForm.h

 #include "FractalScript.h"
 #using <System.Windows.Forms.dll>

 #pragma once

 namespace FractalGenerator {

     using namespace System;
     using namespace System::ComponentModel;
     using namespace System::Collections;
     using namespace System::Windows::Forms;
     using namespace System::Data;
     using namespace System::Drawing;

 public ref class MainForm : public System::Windows::Forms::Form
     {
     public:
         MainForm(void)
         {
             InitializeComponent();
         }

 public:
         void FillRectangleFloat(point::Config^ pConf, bool colour, PaintEventArgs^ e)
         {
             if (colour)
             {
                 SolidBrush^ brush = gcnew SolidBrush(Color::FromArgb(255, 0, 0, 0));
                 e->Graphics->FillRectangle(brush, pConf.x, pConf.y, pConf.width, pConf.height);
             }
             else
             {
                 SolidBrush^ brush = gcnew SolidBrush(Color::White);
                 e->Graphics->FillRectangle(brush, pConf.x, pConf.y, pConf.width, pConf.height);
             }
         }

         point::Config^ pConf{};

           //After this is just a few other variable/function declarations,
           //the windows form designer auto generated code, and some event handlers
           //which are not relevant to the issue
 };
 }

当我尝试引用第 38 行声明的 pConf 的成员时,错误发生在 MainForm.h 的第 29 和 34 行。同样的错误也发生在不同的地方我尝试为成员分配值。 (是的,值的分配确实发生在我调用我尝试引用值的地方显示的函数之前)

    e->Graphics->FillRectangle(brush, pConf.x, pConf.y, pConf.width, pConf.height);

这是一个简单的语法错误,Config 是引用类型,pConf 是对 Config 对象的引用,因此您必须使用 -> 来取消引用成员。 pConf 声明中的 ^ 帽子是您的提示。

不要被 ref struct 搞糊涂了,它不是 value struct,因此也不是您要使用 . 取消引用成员的值类型。它只是 class 的语法等价物,默认情况下所有成员都具有 public 可访问性。受本机 C++ 对待结构 vs class 的方式启发的笨拙。最好避免,将自己限制在 ref classvalue struct

可能打算将 Config 声明为值类型,它确实符合模式。但是不推荐,值类型不应超过 4 个简单字段。较大的效率低下并且通过值复制和传递给函数或从函数传递 return 变得昂贵。值类型的最佳点是它们能够适应可用的 CPU 寄存器。

修复:

    e->Graphics->FillRectangle(brush, pConf->x, pConf->y, pConf->width, pConf->height);