使数据成员随处可访问,但只读

发布于 2024-12-11 06:45:25 字数 2211 浏览 0 评论 0原文

我刚刚开始自己​​的 Windows API 包装器,在重写结构以包含 C++ 功能时遇到了一个不熟悉的主题。

我正在把这个:

typedef struct _RECT {
    LONG left;
    LONG top;
    LONG right;
    LONG bottom;
} RECT, *PRECT;

变成

#define RECT_POS 1
#define RECT_SIZE 2

typedef struct WrapperRect // RECT
{
    WrapperRect(); // all 0
    WrapperRect (const double, const double, const double, const double, bool = RECT_POS); // initalize with tl pos and either br pos or size

    bool set (const double, const double, const double, const double, bool = RECT_POS); // set tl pos and either br pos or size
    bool pos (const double, const double); // set tl pos
    bool size (const double, const double); // set size

    WrapperRect & operator= (const WrapperRect &); // assign another rect
    bool operator== (const WrapperRect &); // check for equality (pos+size)
    bool operator!= (const WrapperRect &); // check for inequality (pos+size)
    bool operator> (const WrapperRect &); // check for tl pos greater
    bool operator< (const WrapperRect &); // check for tl pos less
    bool operator>= (const WrapperRect &); // check for tl pos greater equal
    bool operator<= (const WrapperRect &); // check for tl pos less equal
    WrapperRect & operator+ (const POINT &); // move down/right
    WrapperRect & operator- (const POINT &); // move up/left
    WrapperRect & operator+= (const POINT &); // move down/right
    WrapperRect & operator-= (const POINT &); // move up/left

    double l, left, x; // left
    double r, right; // right
    double t, top, y; // top
    double b, bottom; // bottom

    double w, width; // width
    double h, height; // height
} Rect, rect; // allow more convenient names

我唯一的问题是,如果用户说

Rect myRect;  
myRect.right = 50;

它将设置右侧,但无法更改右侧的别名或宽度。

我也不希望成员是私有的,因为我想要语法

cout << myRect.x;

而不是烦人的

cout << myRect.getX();

语法。
有什么方法可以实现这一点,还是必须使用 get 函数?

编辑:
当我写这篇文章时,我真的没有想到,我添加了一些返回值(>.>)并将operator+等中的双精度更改为一个点。在接受一种可能性之前,我开始尝试各种可能性。

I'm just starting my own Windows API wrapper and I've run into an unfamiliar topic while rewriting a structure to include C++ features.

I'm turning this:

typedef struct _RECT {
    LONG left;
    LONG top;
    LONG right;
    LONG bottom;
} RECT, *PRECT;

into

#define RECT_POS 1
#define RECT_SIZE 2

typedef struct WrapperRect // RECT
{
    WrapperRect(); // all 0
    WrapperRect (const double, const double, const double, const double, bool = RECT_POS); // initalize with tl pos and either br pos or size

    bool set (const double, const double, const double, const double, bool = RECT_POS); // set tl pos and either br pos or size
    bool pos (const double, const double); // set tl pos
    bool size (const double, const double); // set size

    WrapperRect & operator= (const WrapperRect &); // assign another rect
    bool operator== (const WrapperRect &); // check for equality (pos+size)
    bool operator!= (const WrapperRect &); // check for inequality (pos+size)
    bool operator> (const WrapperRect &); // check for tl pos greater
    bool operator< (const WrapperRect &); // check for tl pos less
    bool operator>= (const WrapperRect &); // check for tl pos greater equal
    bool operator<= (const WrapperRect &); // check for tl pos less equal
    WrapperRect & operator+ (const POINT &); // move down/right
    WrapperRect & operator- (const POINT &); // move up/left
    WrapperRect & operator+= (const POINT &); // move down/right
    WrapperRect & operator-= (const POINT &); // move up/left

    double l, left, x; // left
    double r, right; // right
    double t, top, y; // top
    double b, bottom; // bottom

    double w, width; // width
    double h, height; // height
} Rect, rect; // allow more convenient names

My only problem is that if the user were to say

Rect myRect;  
myRect.right = 50;

it will set the right side, but won't be able to change the aliases for the right side, or the width.

I don't want the members to be private either because I want the

cout << myRect.x;

syntax rather than the annoying

cout << myRect.getX();

syntax.
Is there any way to achieve this, or must I use get functions?

edit:
I really wasn't thinking when I wrote this, I've added some return values (>.>) and changed the double in operator+ etc to a point. I'm starting to try the possibilities before I accept one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甲如呢乙后呢 2024-12-18 06:45:25

暴露你的数据成员是非常糟糕的做法。在类中拥有完全相同信息的多个副本也是非常糟糕的做法。它既低效又容易出错。

您肯定需要使用访问器函数。

话虽这么说,你不需要 getX(); - 只要 x() 就可以了。

如果你真的决定避免函数语法,那么我想这样的事情会ok

struct Rect
{
private:
    double l, r, t, b;

public:
    const double &x, &y;

    Rect() : x(r), y(t) {}

    ...etc.
};

然后你可以以安全的方式使用rx,尽管你仍然在某种程度上暴露了你的执行。

It is quite bad practice to expose your data members. It is also really bad practice to have multiple copies of the exact same information inside your classes. It is both inefficient and bug-prone.

You definitely need to use accessor functions.

That being said, you don't need to have getX(); - just x() would be fine.

If you're really set on avoiding function syntax, something like this would be ok I guess:

struct Rect
{
private:
    double l, r, t, b;

public:
    const double &x, &y;

    Rect() : x(r), y(t) {}

    ...etc.
};

Then you could use r.x in a safe fashion though you are still somewhat exposing your implementation.

梦里南柯 2024-12-18 06:45:25

您应该使用获取函数。您不想要您声称想要的语法。

例如,假设您稍后更改函数以将 x 值和 y 值一起编码为某种复杂的结构。那么你将如何让myRect.x工作呢?

假设检索 x 的值很少见。所以除非必要,否则你不想计算它。那么你将如何让myRect.x工作呢?

假设在将来的某个时刻,您需要计算 x 被访问了多少次。那么你将如何让 myRec.x 工作呢?

使用 get 函数,这样您就不会强制只想获取 x 值的代码了解它在类中的存储方式。

You should use get functions. You don't want the syntax you claim you want.

For example, suppose you later change the function to encode both the x and they y values together into some complex structure. How will you make myRect.x work then?

Say retrieving the value of x is rare. So you don't want to compute it unless you have to. How will you make myRect.x work then?

Say at some point in the future, you need to count how many times x has been accessed. How will you make myRec.x work then?

Use get functions so that you don't force code that just wants to get the value of x to understand how it's stored inside the class.

倒数 2024-12-18 06:45:25

您可以使用常量指针。 const double * xPtr; 然后在构造函数中对其进行初始化:xPtr = &x 这将创建一个指向 x 的指针,该指针不能用于修改x。尽管要更改值 x 本身,但您肯定需要一个 setter 函数。

正如已经指出的,这是不好的做法,您最好使用具有私有成员、访问器等的类。

const 指针类型参考此处:

http://www.codeguru.com/cpp/cpp/cpp_mfc/general/article.php/c6967

You could use a constant pointer. const double * xPtr; then initialize it in the constructor: xPtr = &x this creates a pointer to x that cannot be used to modify x. You would definitely need a setter function, though to change the value x itself.

As has been noted, this is bad practice and you're better off using a class with private members, accessors, etc.

const pointer types reference here:

http://www.codeguru.com/cpp/cpp/cpp_mfc/general/article.php/c6967

眼泪都笑了 2024-12-18 06:45:25

这可能不会为我赢得很多编码信誉”,但实际上,当您创建的内容非常像负责大部分工作的 ac 结构时,我实际上并不认为直接访问成员是一种糟糕的风格。用于存储数据而不负责更高级别的智能。所以你的问题的答案是使用联合

struct rect
{
    union
    {
        double width;
        double w;
    };

    union
    {
        double height;
        double h;
    };
}

当你这样做时,访问 h 和访问 height 实际上访问内存中的相同位置。

This might not earn me a lot of coding cred' but I actually don't think that it's such bad style to access members directly when what you're creating is very much like a c struct that is responsible mostly for storing data and not responsible for a higher level of intelligence. So the answer to your question is to use a union

struct rect
{
    union
    {
        double width;
        double w;
    };

    union
    {
        double height;
        double h;
    };
}

When you do this, then accessing h and accessing height actually access the same location in memory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文