使数据成员随处可访问,但只读
我刚刚开始自己的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
暴露你的数据成员是非常糟糕的做法。在类中拥有完全相同信息的多个副本也是非常糟糕的做法。它既低效又容易出错。
您肯定需要使用访问器函数。
话虽这么说,你不需要 getX(); - 只要 x() 就可以了。
如果你真的决定避免函数语法,那么我想这样的事情会ok:
然后你可以以安全的方式使用
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:
Then you could use
r.x
in a safe fashion though you are still somewhat exposing your implementation.您应该使用获取函数。您不想要您声称想要的语法。
例如,假设您稍后更改函数以将 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 makemyRect.x
work then?Say at some point in the future, you need to count how many times
x
has been accessed. How will you makemyRec.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.
您可以使用常量指针。
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 tox
that cannot be used to modifyx
. You would definitely need a setter function, though to change the valuex
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
这可能不会为我赢得很多编码信誉”,但实际上,当您创建的内容非常像负责大部分工作的 ac 结构时,我实际上并不认为直接访问成员是一种糟糕的风格。用于存储数据而不负责更高级别的智能。所以你的问题的答案是使用联合
当你这样做时,访问 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
When you do this, then accessing h and accessing height actually access the same location in memory.