通过引用授予子级访问父级成员的权限 - 可以吗?
C++新手问题。 请验证我做得是否正确。
我有一个全局应用程序类生成它的小孩子,我需要让孩子们访问一些应用程序设施。 所以我决定把它们传给孩子们参考。
我测试了这个想法,如下所示。 看起来效果很好。 我只是想确保我没有做危险的事情。 可能有我忽略的陷阱吗?
爸爸创造了孩子并给了他们他的车钥匙:
#include <iostream>
using namespace std;
class CCarKeys
{
public:
CCarKeys(const string& Name) : _Name(Name) {}
string _Name;
};
class CChild
{
public:
CChild(CCarKeys& CarKeys) : _Name("Child"), _CarKeys(CarKeys) {}
string _Name;
CCarKeys& _CarKeys;
void TestHasKeys() {cout << "I got " << _CarKeys._Name << endl;}
};
class CDad
{
public:
CDad() : _Name("Dad"), _HondaCarKeys("Honda keys"), _ChevyCarKeys("Chevy keys") {}
string _Name;
CCarKeys _HondaCarKeys;
CCarKeys _ChevyCarKeys;
CChild *_Boy;
CChild *_Girl;
void MakeBoy() {_Boy= new CChild(_HondaCarKeys);}
void MakeGirl() {_Girl= new CChild(_ChevyCarKeys);}
};
int main ()
{
CDad Dad;
Dad.MakeBoy();
Dad.MakeGirl();
Dad._Boy->TestHasKeys();
Dad._Girl->TestHasKeys();
}
C++ newbie question. Please, verify I'm doing it right.
I have a global application class spawning it's little kids and I need to give the kids access to some of the application facilities. So I decided to pass them to children by reference.
I tested the idea as show below. It seems to work fine. I just wanted to make sure I'm not doing something dangerous. Might be there any pitfalls I overlooked?
Dad creates children and gives them his car keys:
#include <iostream>
using namespace std;
class CCarKeys
{
public:
CCarKeys(const string& Name) : _Name(Name) {}
string _Name;
};
class CChild
{
public:
CChild(CCarKeys& CarKeys) : _Name("Child"), _CarKeys(CarKeys) {}
string _Name;
CCarKeys& _CarKeys;
void TestHasKeys() {cout << "I got " << _CarKeys._Name << endl;}
};
class CDad
{
public:
CDad() : _Name("Dad"), _HondaCarKeys("Honda keys"), _ChevyCarKeys("Chevy keys") {}
string _Name;
CCarKeys _HondaCarKeys;
CCarKeys _ChevyCarKeys;
CChild *_Boy;
CChild *_Girl;
void MakeBoy() {_Boy= new CChild(_HondaCarKeys);}
void MakeGirl() {_Girl= new CChild(_ChevyCarKeys);}
};
int main ()
{
CDad Dad;
Dad.MakeBoy();
Dad.MakeGirl();
Dad._Boy->TestHasKeys();
Dad._Girl->TestHasKeys();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
通过引用传递与通过指针传递完全相同,除了语义之外,以及如果通过引用传递,您无法对指针本身执行任何操作。
你的代码没问题。
Passing by reference is quite the same that passing by pointer except for semantics and the fact that you can do nothing with the pointer itself if passing by reference.
Your code is OK.
在您的特定情况下,汽车钥匙不太可能被永久授予,而是根据需要进行请求并根据每个请求授予。 因此,
在主应用程序类和子级的更一般情况下,如何在 main() 中创建由应用程序和子级共享的数据对象,并将引用传递给每个人。
In your particular case, car keys aren't likely to be granted permanently, but rather requested as needed and granted on per-request basis. So it's more
In more genral case of main app class and children, how about creating the data object shared by app and children in main(), and passing thereferences to everybody.
这是可能的,并且在您的代码中不会造成伤害。 但这很危险,因为如果复制 CDad,那么键和指针也会随之复制。 但是,指针指向的对象以及这些对象内部的引用将保持不变。 如果原始 CDad 对象超出范围,则指针引用的对象中的引用将悬空,不再引用有效对象。
也许你可以逆转生命周期:在堆上创建键,并将孩子作为类中的普通成员。 因此,如果你复制爸爸,孩子们就会被复制,但钥匙不会。 我认为密钥是不可变的,因此您可以在多个孩子之间共享相同的密钥。
这引出了另一点:如果您的密钥相当小(读:不是很大)并且不可变(因此,如果您更改一个密钥而不是其他密钥,则不会出现更新异常),请考虑创建它不 也在堆上 - 所以它们也会自动复制,并在孩子们需要密钥时将它们传递给他们。 你可以让它们成为孩子们的普通指针,但我认为这很丑陋,因为孩子不包含钥匙 - 但使用它。 因此,指针/引用或函数参数很适合,但不是“真正的”数据成员。
如果您要使用共享密钥和堆上密钥,您应该使用智能指针 - 因为您必须跟踪所有孩子和爸爸。 如果最后一个孩子/爸爸超出了范围,您必须再次删除该密钥。 为此,您可以使用 boost::shared_ptr :
当然,您可以通过使 CDad 类不可复制来避免所有这些复杂性。 然后您可以使用原来的解决方案,只需让孩子们使用shared_ptr并使孩子们也不可复制。 理想情况下,应该使用非共享指针,例如auto_ptr,但是auto_ptr也有一些陷阱,而shared_ptr都避免了:
如果我必须实现这样一个类层次结构,我会这样做解决方案,或者只是将密钥作为成员删除,并在需要时将它们传递/创建给子级。 关于代码的其他一些注意事项:
It's possible and in your code it's not causing harm. But it's dangerous, because if you copy CDad, then the keys and pointers will be copied along. The objects that the pointers will point to, and the reference inside those objects, however, will remain the same. If the original CDad object then goes out of scope, the references in the objects referenced by the pointers are dangling, referencing no valid object anymore.
Maybe you can to reverse lifetimes: Create the keys on the heap, and the kids as normal members within the class. So if you copy dad, the kids are copied, but the keys are not. I think keys are immutable, so you can share the same key among multiple kids.
This brings to another point: If your keys are reasonable small (read: not huge) and immutable (so you don't have update anomalies if you change one key, but not the others), consider creating it not on the heap too - so they are automatically copied along too, and pass them to the kids when they need the key. You can make them normal pointers of the kids, but i think that's ugly, because the kid does not contain a key - but uses it. So a pointer/reference or a function parameter fits well, but not a "real" data member.
If you are going with the shared key and the keys-on-heap, you should use smart pointers - because you have to keep track of all kids and dads. If the last kid/dad goes out of scope, you have to delete the key again. You use
boost::shared_ptr
for that:Of course, you can avoid all this complexity by just making the CDad class non-copyable. Then you can use your original solution, just with making the kids use a shared_ptr and make the kids non-copyable too. Ideally, one should use a non-shared pointer, such as
auto_ptr
, but that auto_ptr has some pitfalls too, which shared_ptr all avoids:If i had to implement such a class hierarchy, i would go with that solution, or just drop the keys as members, and pass/create them when needed to the children. Some other notes about your code:
对我来说看起来不错(如果他们只需要钥匙的话)。 他们可能需要爸爸提供一些稍后请求的其他服务 - 例如:
但他们没有爸爸的参考资料,所以他们无法做到这一点。 所以我会让 CChild 构造函数也采用
this
引用。然后
,
CChild
构造函数需要采用ICashProvider
和IChaffeur
,CWife
和CGirlfriend 也是如此
(也许还有CBoyfriend
)。 此时,我想您可能会意识到,面对Dad
的职责,这种粒度级别毫无意义,您只需将this
交给每个人,然后让Dad
通过强制调用者在某些方法上发送自己的this
来验证请求,这样您就不会让Dad
执行乱伦或更改CWife
代码>的尿布。Looks good to me (if keys is all they need). They might need some other services from Dad which are requested later - like:
But they don't have a reference to Dad, so they won't be able to do that. So I would have the CChild constructor take a
this
reference, too.etc.
And then
CChild
constructor would need to takeICashProvider
andIChaffeur
, as wouldCWife
andCGirlfriend
(andCBoyfriend
, perhaps). At this point, I think you might realize that this level of granularity is pointless in the face ofDad
's responsibilities and you just give everyonethis
and haveDad
authenticate requests by forcing callers to send their ownthis
on some methods, so you don't haveDad
performing incest or changing theCWife
's diaper.