【问题标题】:Translating get/set from C# to C++, using header files使用头文件将 get/set 从 C# 转换为 C++
【发布时间】:2014-09-13 20:07:18
【问题描述】:

作为前言,我正在重建一个旧游戏项目的基本结构。它是用 C# 编写的,我正在尽我所能将我拥有的东西转换成 C++。我也在使用 Visual Studio Professional 2013。在这种情况下,我有一个 Coordinate 类,可以动态获取和设置其 X 和 Y 属性的值。总而言之,它相当简单。

这是 C# 类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConquestGameEngine.Map
{

    public class Coordinate
    {
        public int X { get; set; }
        public int Y { get; set; }
        public Coordinate(int x, int y)
        {
            this.X = x;
            this.Y = y;
        }
    }
}

这里是 C++ 类和头文件:

//Coordinate.h
#pragma once
class Coordinate
{
public:
    Coordinate(int x, int y)
    {
        X = x;
        Y = y;
    }
    ~Coordinate();
    int X, Y;
};

//Coodinate.cpp
using namespace std;
#include "Coordinate.h"

Coordinate::Coordinate(int x, int y)
{
    Coordinate::X = x;
    Coordinate::Y = y;
}

Coordinate::~Coordinate()
{
}

以我有限的知识和经验,以及我所做的研究/学习,我对头文件的功能和用途以及如何使用它们有了相当好的把握。但是我越是尝试重新创建在 C# 中建立的 get-set 原则,我越是对是否应该将某些内容放入 .h 或 .cpp 感到困惑。在熟悉库以及如何使用它时,我也很菜鸟,所以我不知道是否还有其他方法可以解决它。我在网上找到的所有示例都无法与我的问题或回答我的问题相提并论,或者过于笼统或过于具体而无法提供帮助。

还有一个名为 TilePattern 的类的次要问题,它由坐标列表组成,但我觉得一旦我弄清楚了这个坐标问题,我就可以自己解决这个问题。

所以我忽略了一些非常简单的事情吗?是新手的错误吗?这只是 C++ 中的复杂得多吗?库中是否有我不知道的工具可以解决所有这些问题?

【问题讨论】:

  • 你的构造函数已经在header中实现了,不需要在cpp文件中重新定义。此外,C++ 没有属性,因此使用预处理器魔法来模拟这种行为是一种丑陋的 hack。在这种特定情况下,将 X 和 Y 保留为公共字段/成员变量是完全可以的。

标签: c# c++ class constructor header


【解决方案1】:

首先,看起来您在
中都定义了构造函数 标头,然后在 cpp.这是一对多。
其次,如果Coordinate 对更改没有“反应”,那么您想要的是
大概是这样的:

struct Coordinate {
    int x,y;
};

不要过度设计它。它仍然可以像这样使用

return Coordinate{5,7} ;

之类的。如果您确实需要 getter、setter 方法来报告
更改,检查其内部债券等,是的,这在 C++ 中有点冗长,
如果你必须有赋值语法,否则一个常见的方法是:

int X() { return x; }
void X(int xx) { x=xx; report_change(); }

【讨论】:

  • 重复构造函数是一个愚蠢的错误。所以我现在已经从 .cpp 中消除了它,但它仍然需要两个整数,因为构造函数是如何在 .h 中定义的。所以我很困惑如何获取和设置 X 和 Y 值作为调用构造函数的 .cpp 的输入。你说的有点像它的工作,但我不确定我是否理解它......你能再解释一下吗?或者,我可以查找以尝试为自己找出答案的事物的名称是什么?
  • 对于这么简单的类型,你真的不需要构造函数。查看uniform initialization
【解决方案2】:

我前段时间在我的网站上发布了一个解决方案:http://www.cbuilderblog.com/una-classe-template-alternativa-a-__property/

我建议使用模板类来实现 get/set 属性。

这是模板类:

    // Template class for __property construct emulation
template< typename owner_t, typename prop_t, void (owner_t::*setter)(prop_t), prop_t (owner_t::*getter)() >
class CProperty
{
public:
  // Constructor
  CProperty(owner_t* owner){m_owner = owner;}

  // op = overloading
  void operator=(prop_t value)
  {
    return (m_owner->*setter)(value);
  }
  // op type overloading
  operator prop_t()
  {
    return (m_owner->*getter)();
  }
private:
  owner_t* m_owner;
};

这是一个在 CPanel 类中使用的示例,它声明了一些属性:

class CPanel
{
private:
  int m_Width;  // Private member for Width property
  int m_Height; // Private member for Height property

protected:
  void __fastcall SetWidth(int AValue); // Set the Width property  
  int __fastcall  GetWidth();           // Get the Width property

  void __fastcall SetHeight(int AValue);// Set the Height property
  int  __fastcall GetHeight();          // Get the Height property

public:
  CPanel()
  :Width(this), Height(this)
  {
  }

  CProperty<CPanel, int, SetWidth,  GetWidth>  Width;
  CProperty<CPanel, int, SetHeight, GetHeight> Height;
}

如果您需要更多帮助,可以在评论部分提问。

【讨论】:

    【解决方案3】:

    是的,不要过度编译它

    我会做这样的事情

    //Coordinate.h
    class Coordinate
    {
    private:
       int m_x;
       int m_y;
    public:
       Coordinate(const int& x_, const int& y_):m_x(x),m_y(y){}
       Coordinate():m_x(0),m_y(0){}
    
       const int& x() const;
       void x(const int& x_);
    
       //For these methods I would do it inline like this.
       const int& y() const {return m_y;}
       void y(const int& y_) {m_y = y_;}
    };
    
    //Coordinate.cpp (if used)
    const int& Coordinate::x() {return m_x;}
    void Coordinate::x(const int& x_) {m_x = x_;}
    

    请注意,get/set 在 C++ 中的使用并不多,C++ 获取名称的方式就是说name()。设置名称可能需要set_name(const std::string&amp; name),但我通常更喜欢简约的void name(const std::string&amp; name),当它与getter name() 配对时才有意义。

    你也可以这样做

    class Coordinate
    {
    ...
    public:
       int& x(){return m_x;}
    ...
    };
    

    并将其用作

    Coordinate c(3,4);
    std::cout<<c.x()<<std::endl;
    c.x() = 17;
    std::cout<<c.x()<<std::endl;
    

    哪个会打印

    3
    17
    

    但是,最后一种方法会暴露类的内部实现细节,应该避免。

    【讨论】:

      猜你喜欢
      • 2020-01-31
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-01
      • 2010-10-18
      • 2018-07-08
      • 1970-01-01
      相关资源
      最近更新 更多